Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Программа изменения свойства наследования дескриптора
#include < windows.h> #include < conio.h> volatile int count; void thread() { for (;; ) { count++; Sleep(500); _cprintf (" count = %d\n", count); } } int main() { // имя нового процесса с пробелом char lpszComLine[80]=" C: \\ConsoleProcess.exe "; // для символьного представления дескриптора char lpszHandle[20]; STARTUPINFO si; PROCESS_INFORMATION pi; HANDLE hThread; DWORD IDThread; _cputs(" Press any key to start the count-thread.\n" ); _cputs(" After terminating the thread press any key to exit.\n" ); _getch(); // запускаем поток-счетчик hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, NULL, 0, & IDThread); if (hThread == NULL) return GetLastError(); // делаем дескриптор потока наследуемым if(! SetHandleInformation( hThread, // дескриптор потока HANDLE_FLAG_INHERIT, // изменяем наследование дескриптора HANDLE_FLAG_INHERIT)) // делаем дескриптор наследуемым { _cputs(" The inheritance is not changed.\n" ); _cputs(" Press any char to finish.\n" ); _getch(); return GetLastError(); } // устанавливаем атрибуты нового процесса ZeroMemory(& si, sizeof(STARTUPINFO)); si.cb=sizeof(STARTUPINFO); // преобразуем дескриптор в символьную строку _itoa((int)hThread, lpszHandle, 10); // создаем командную строку strcat(lpszComLine, lpszHandle); // запускаем новый консольный процесс if (! CreateProcess( NULL, // имя процесса lpszComLine, // адрес командной строки NULL, // атрибуты защиты процесса по умолчанию NULL, // атрибуты защиты первичного потока по умолчанию TRUE, // наследуемые дескрипторы текущего процесса // наследуются новым процессом CREATE_NEW_CONSOLE, // новая консоль NULL, // используем среду окружения процесса-предка NULL, // текущий диск и каталог, как и в процессе-предке & si, // вид главного окна - по умолчанию & pi // здесь будут дескрипторы и идентификаторы // нового процесса и его первичного потока ) ) { _cputs(" The new process is not created.\n" ); _cputs(" Press any key to finish.\n" ); _getch(); return GetLastError(); } // закрываем дескрипторы нового процесса CloseHandle(pi.hProcess); CloseHandle(pi.hThread); _getch(); // закрываем дескриптор потока CloseHandle(hThread); return 0; }
События Объекты-события используются для уведомления ожидающих нитей о наступлении какого-либо события. Различают два вида событий - с ручным и автоматическим сбросом. Ручной сброс осуществляется функцией ResetEvent. События с ручным сбросом используются для уведомления сразу нескольких нитей. При использовании события с автосбросом уведомление получит и продолжит свое выполнение только одна ожидающая нить, остальные будут ожидать дальше. Функция CreateEvent создает объект-событие, SetEvent - устанавливает событие в сигнальное состояние, ResetEvent - сбрасывает событие. Функция PulseEvent устанавливает событие, а после возобновления ожидающих это событие нитей (всех при ручном сбросе и только одной при автоматическом), сбрасывает его. Если ожидающих нитей нет, PulseEvent просто сбрасывает событие. Пример. Синхронизация нитей с помощью событий. #include < windows.h> #include < stdio.h> HANDLE hEvent1, hEvent2; int a[5]; HANDLE hThr; unsigned long uThrID; void Thread( void* pParams ) { int i, num = 0; while (1){ WaitForSingleObject( hEvent2, INFINITE ); for (i=0; i< 5; i++) a[i] = num; num++; SetEvent( hEvent1 ); } }
int main( void ) { hEvent1=CreateEvent( NULL, FALSE, TRUE, NULL ); hEvent2=CreateEvent( NULL, FALSE, FALSE, NULL ); hThr=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread, NULL, 0, & uThrID); while(1) { WaitForSingleObject( hEvent1, INFINITE ); printf(" %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4]); SetEvent( hEvent2 ); } return 0; }
Идентификация процессов. Параметры Идентификация процессов Процесс может получить идентификатор и дескриптор нового дочернего процесса из структуры PROCESS_INFORMATION. Закрытие дескриптора дочернего процесса уничтожает только возможность доступа к нему родительского процесса. Для получения описания текущего процесса используется пара функций. HANDLE GetCurrentProcess (VOID) DWORD GetCurrentProcessId (VOID) Функция GetCurrentProcess в действительности возвращает псевдодескриптор, который не может быть унаследован. Это значение используется в случаях, когда процессу требуется собственный дескриптор. Создавайте настоящий дескриптор процесса из его ID, используя в вызове функции OpenProcess значение, возвращенное функцией GetCurrentProcessId. HANDLE OpenProcess ( DWORD fdwAccess, BOOL fInherit, DWORD IDProcess) Возвращаемое значение: дескриптор процесса или NULL в случае ошибки. Параметр fdwAccess определяет параметры доступа процесса к дескриптору. Приведем некоторые из его возможных значений. • Флаг SYNCHRONIZE разрешает другим процессам ждать завершения этого процесса, используя функции ожидания • PROCESS_ALL_ACCESS — установлены все флаги доступа. • Флаг PROCESS_TERMINATE делает возможным завершение процесса вызовом функции TerminateProcess. • Флаг PROCESS_QUERY_INFORMATION разрешает использовать дескриптор функциями GetExitCodeProcess и GetPriorityClass для получения информации о процессе. И наконец, выполняющийся процесс может определить имя своего загрузочного файла с помощью функции GetModuleFileName, используя в качестве параметра hModule указатель NULL. Вызов этой функции из динамической библиотеки возвратит имя файла DLL, а не файла.ЕХЕ, используемого библиотекой. |
Последнее изменение этой страницы: 2019-04-09; Просмотров: 205; Нарушение авторского права страницы