Windows для профессионалов


Преобразование псевдоописателя в настоящий описатель - часть 2


&hThreadParent, // даст новый настоящий описатель идентифицирующий родительский поток;
0, // игнорируется из-за DUPLICATE_SAME_ACCESS FALSE, новый описатель потока ненаследуемый, DUPLICATE_SAME_ACCESS); // новому описателю потока присваиваются те же атрибуты защиты, что и псевдоописателю

CreateThread(NULL, 0, ChildThread, (PVOID) hThreadParent, 0, NULL) ;

// далее следует какой-то код
}

DWORD WINAPI ChildThread(PVOID pvParam)
{

HANDLE hThreadParent = (HANDLE) pvParam;

FILETIME ftCreaUonTime, ftExitTime, ftKernelTime, ftUserTime;

GetThreadTimes(hThreadParent, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);

CloseHandle(hThreadParent);

// далее следует какой-то код..
}

Тeпeрь родительский поток преобразует свой "двусмысленный" псевдоописатель в настоящий описатель, однозначно определяющий родительский поток, и передает его в CreateThread. Когда дочерний поток начинает выполнение, его параметр pvParam содержит настоящий описатель потока. В итоге вызов какой-либо функции с этим описателем влияет не на дочерний, а на родительский поток.

Поскольку DuplicateHandle увеличивает счетчик пользователей указанного объекта ядра, то, закончив работу с продублированным описателем объекта, очень важно не забыть уменьшить счетчик. Сразу после обращения к GetThreadTimes дочерний поток вызывает CloseHandle, уменьшая тем самым счетчик пользователей объекта "родительский поток" на 1. В этом фрагменте кода я исходил из того, что дочерний поток не вызывает других функций с передачей этого описателя. Если же ему надо вызвать какие-то функции с передачей описателя родительского потока, то, естественно, к CloseHandle следует обращаться только после тогo, как необходимость в этом описателе у дочернего потока отпадет.

Надо заметить, что DuphcateHandle позволяет преобразовать и псевдоописатель процесса. Вот как это сделать:

HANDLE hProcess;

DuplicateHandle( GetCurrentProcess(), // Описатель процесса, к которому // относится псевдоописатель GetCurrentProcess(), // Псевдоописатель процесса GetCurrentProcess(), // Описатель процесса, к которому // относится настоящий описатель &hProcess, // Дает новый, настоящий описатель, // идентифицирующий процесс 0, // Игнорируется из-за DUPLICATE_SAME_ACCESS FALSE, // Новый описатель процесса ненаследуемый DUPLICATE_SAME_ACCESS); // Новому описателю процесса присваиваются // те же атрибуты защиты, что и псевдоописателю




Начало  Назад  Вперед



Книжный магазин