Рассмотрим этот пример кода для LookupPrivilegeValue, взятого из MSDN (с незначительными правками форматирования кода)
BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
TOKEN_PRIVILEGES tp;
LUID luid;
if ( !LookupPrivilegeValue(NULL, lpszPrivilege, &luid ) ) {
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}
// SET A BREAKPOINT BELOW, notice a new thread was created
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege) {
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else {
tp.Privileges[0].Attributes = 0;
}
// Enable the privilege or disable all privileges.
if ( !AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) {
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
Используя отладчик VS 2010/2008 после первого вызова LookupPrivilegeValue, я заметил, что был создан новый рабочий поток с именем _TppWaiterpThread @ 4. Этот поток живет до тех пор, пока не завершится процесс, а его трассировка стека будет следующей:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwWaitForMultipleObjects@20() + 0xc bytes
ntdll.dll!_TppWaiterpThread@4() + 0x12c bytes
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Протестировано на Windows 7 x86 / x64 (удаленная / локальная отладка). Я попытался установить две привилегии SE_DEBUG_NAME & SE_SYSTEM_NAME. Вот как я назвал SetPrivilege:
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());
SetPrivilege(hProcess, SE_SYSTEMTIME_NAME, TRUE);
//SetPrivilege(hProcess, SE_DEBUG_NAME, TRUE);
На XP эта новая тема не появляется.
Итак, мои вопросы:
Это часть внутренней реализации рабочего завода. Как правило, один поток на фабрику используется для ожидания всех ожидаемых событий. Когда происходит событие, поток официанта отправляет задание одному из рабочих потоков для обработки события.
Это все часть tpWorkerFactory реализация.
Других решений пока нет …