Составители:
Рубрика:
но превратить псевдоописатель процесса в настоящий описатель, действу-
ющий только в текущем процессе:
HANDLE hrealThread;
DuplicateHandle(
GetCurrentProcess(), GetCurrentProcess(),
GetCurrentProcess(), &hrealThread,
DUPLICATE_SAME_ACCESS, FALSE, 0
);
У процессов и потоков есть интересная особенность – объекты ядра,
представляющие процесс и поток, сразу после создания имеют счетчик
использования не менее двух: во-первых, это описатель, возвращенный
функцией, и, во-вторых, объект используется работающим потоком.
В итоге завершение потока и завершение последнего потока в процессе
не приводят к удалению соответствующих объектов – они будут сохра-
няться все время, пока существуют их описатели. Это сделано для того,
чтобы уже после завершения работы потока или процесса можно было по-
лучить от него какую-либо информацию, чаще всего – код завершения
(функции GetExitCodeThread и GetExitCodeProcess);
Объекты ядра «процесс» и «поток» поддерживают также интерфейс
синхронизируемых объектов, так что их можно использовать для синхро-
низации работы: поток считается занятым до завершения, а процесс занят
до тех пор, пока в нем есть хоть один работающий поток.
Если ни синхронизация с этими объектами, ни получение кодов за-
вершения не требуются разработчику, надо сразу после создания соответ-
ствующего объекта закрывать его описатель.
В Windows для задания приоритета работающего потока используют
понятия классов приоритетов и относительных приоритетов в классе. При
этом класс приоритета связывается с процессом, а относительный при-
оритет – с потоком, исполняющимся в данном процессе.
Соответственно Win32 API предоставляет функции для изменения
класса приоритета для процесса (GetPriorityClass, SetPriorityClass) и
для изменения относительного приоритета потока (GetThreadPriority и
SetThreadPriority).
Планировщик операционной системы может динамически коррек-
тировать приоритет потока, кратковременно повышая уровень. Разработ-
чикам предоставлена возможность отказаться от этой возможности или,
наоборот, задействовать ее (функции GetProcessPriorityBoost,
SetProcessPriorityBoost, GetThreadPriorityBoost и
SetThreadPriorityBoost).
Основы многозадачности
211
BOOL DuplicateHandle(
HANDLE hFromProcess, HANDLE hSourceHandle,
HANDLE hToProcess, LPHANDLE lpResultHandle,
DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions
);
Существенно проследить, чтобы все создаваемые описатели закрыва-
лись вызовом функции CloseHandle, включая описатели, созданные функ-
цией DuplicateHandle. Хорошая практика при разработке приложений –
проводить мониторинг выделяемых описателей и количества объектов в
процессе (например, с помощью таких стандартных средств как менеджер
задач или оснастка «производительность» панели управления).
6.2.3.2. Описатели процесса и потока
Для взаимодействия потоков и процессов между собой необходимы
средства, обеспечивающие идентификацию соответствующих объектов.
В Windows для идентификации процессов и потоков используют их описа-
тели (HANDLE) и идентификаторы (DWORD). Описатели идентифицируют в
данном случае объект ядра, представляющий процесс или поток, при дос-
тупе к которому, как ко всякому объекту ядра, учитывается контекст защи-
ты, проверяются права доступа и т.д. Идентификаторы процесса и потока,
назначаемые при их создании, исполняют роль уникальных имен.
Описатели и идентификаторы процессов и потоков можно получить
при создании соответствующих объектов. Кроме того, можно узнать иден-
тификаторы текущего процесса и потока (GetCurrentThreadId,
GetCurrentProcessId), или по описателю узнать соответствующий иденти-
фикатор (GetProcessId и GetThreadId). Функции OpenProcess и OpenThread
позволяют получить описатели этих объектов по их идентификатору.
Функции GetCurrentProcess и GetCurrentThread возвращают описате-
ли текущего процесса и потока, однако возвращаемое ими значение не яв-
ляется настоящим описателем, а представлено некоторой константой, по-
лучившей название «псевдоописатель». Эта константа, использованная
вместо описателя потока или процесса, рассматривается как описатель
процесса/потока, сделавшего вызов системной функции. Псевдоописате-
лями можно свободно пользоваться в рамках процесса (потока), в котором
они получены, а при попытке передать их другому процессу или потоку
они будут рассматриваться как описатели того процесса (потока), в кон-
тексте которого используются.
В тех случаях, когда необходимо дать другому процессу или потоку
доступ к данным описателям, нужно с помощью DuplicateHandle сделать с
них «копии», которые будут являться настоящими описателями в контек-
сте процесса-получателя. Так, например, с помощью этой функции мож-
210
CIL и системное программирование в Microsoft .NET
210 CIL и системное программирование в Microsoft .NET Основы многозадачности 211 BOOL DuplicateHandle( но превратить псевдоописатель процесса в настоящий описатель, действу- HANDLE hFromProcess, HANDLE hSourceHandle, ющий только в текущем процессе: HANDLE hToProcess, LPHANDLE lpResultHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions HANDLE hrealThread; ); DuplicateHandle( Существенно проследить, чтобы все создаваемые описатели закрыва- GetCurrentProcess(), GetCurrentProcess(), лись вызовом функции CloseHandle, включая описатели, созданные функ- GetCurrentProcess(), &hrealThread, цией DuplicateHandle. Хорошая практика при разработке приложений – DUPLICATE_SAME_ACCESS, FALSE, 0 проводить мониторинг выделяемых описателей и количества объектов в ); процессе (например, с помощью таких стандартных средств как менеджер задач или оснастка «производительность» панели управления). У процессов и потоков есть интересная особенность – объекты ядра, представляющие процесс и поток, сразу после создания имеют счетчик 6.2.3.2. Описатели процесса и потока использования не менее двух: во-первых, это описатель, возвращенный Для взаимодействия потоков и процессов между собой необходимы функцией, и, во-вторых, объект используется работающим потоком. средства, обеспечивающие идентификацию соответствующих объектов. В итоге завершение потока и завершение последнего потока в процессе В Windows для идентификации процессов и потоков используют их описа- не приводят к удалению соответствующих объектов – они будут сохра- тели (HANDLE) и идентификаторы (DWORD). Описатели идентифицируют в няться все время, пока существуют их описатели. Это сделано для того, данном случае объект ядра, представляющий процесс или поток, при дос- чтобы уже после завершения работы потока или процесса можно было по- тупе к которому, как ко всякому объекту ядра, учитывается контекст защи- лучить от него какую-либо информацию, чаще всего – код завершения ты, проверяются права доступа и т.д. Идентификаторы процесса и потока, (функции GetExitCodeThread и GetExitCodeProcess); назначаемые при их создании, исполняют роль уникальных имен. Объекты ядра «процесс» и «поток» поддерживают также интерфейс Описатели и идентификаторы процессов и потоков можно получить синхронизируемых объектов, так что их можно использовать для синхро- при создании соответствующих объектов. Кроме того, можно узнать иден- низации работы: поток считается занятым до завершения, а процесс занят тификаторы текущего процесса и потока (GetCurrentThreadId, до тех пор, пока в нем есть хоть один работающий поток. GetCurrentProcessId), или по описателю узнать соответствующий иденти- Если ни синхронизация с этими объектами, ни получение кодов за- фикатор (GetProcessId и GetThreadId). Функции OpenProcess и OpenThread вершения не требуются разработчику, надо сразу после создания соответ- позволяют получить описатели этих объектов по их идентификатору. ствующего объекта закрывать его описатель. Функции GetCurrentProcess и GetCurrentThread возвращают описате- В Windows для задания приоритета работающего потока используют ли текущего процесса и потока, однако возвращаемое ими значение не яв- понятия классов приоритетов и относительных приоритетов в классе. При ляется настоящим описателем, а представлено некоторой константой, по- этом класс приоритета связывается с процессом, а относительный при- лучившей название «псевдоописатель». Эта константа, использованная оритет – с потоком, исполняющимся в данном процессе. вместо описателя потока или процесса, рассматривается как описатель Соответственно Win32 API предоставляет функции для изменения процесса/потока, сделавшего вызов системной функции. Псевдоописате- класса приоритета для процесса (GetPriorityClass, SetPriorityClass) и лями можно свободно пользоваться в рамках процесса (потока), в котором для изменения относительного приоритета потока (GetThreadPriority и они получены, а при попытке передать их другому процессу или потоку SetThreadPriority). они будут рассматриваться как описатели того процесса (потока), в кон- Планировщик операционной системы может динамически коррек- тексте которого используются. тировать приоритет потока, кратковременно повышая уровень. Разработ- В тех случаях, когда необходимо дать другому процессу или потоку чикам предоставлена возможность отказаться от этой возможности или, доступ к данным описателям, нужно с помощью DuplicateHandle сделать с наоборот, задействовать ее (функции GetProcessPriorityBoost, них «копии», которые будут являться настоящими описателями в контек- SetProcessPriorityBoost, GetThreadPriorityBoost и сте процесса-получателя. Так, например, с помощью этой функции мож- SetThreadPriorityBoost).
Страницы
- « первая
- ‹ предыдущая
- …
- 110
- 111
- 112
- 113
- 114
- …
- следующая ›
- последняя »