Составители:
Рубрика:
но превратить псевдоописатель процесса в настоящий описатель, действу-
ющий только в текущем процессе:
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
- …
- следующая ›
- последняя »
