Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Программа изменения свойства наследования дескриптора



 

#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; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.02 с.)
Главная | Случайная страница | Обратная связь