Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Ожидание завершения процессов

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

 

Из содержательных соображений непосредственно вытекает, что такая операция должна задаваться информацией вида

ждать_завершения_процесса(какой_процесс_ждать),

кроме того, в вызов этой функции может быть включен возвращаемый параметр, который позволяет получить код завершения процесса, обычно формируемый функцией exit(код_возврата).

Наиболее мощные, но и сложные средства ожидания завершения процесса использованы в OS/2. Во-первых, процесс, завершение которого предполагается не только ожидать, но и получить от него значение кода завершения, должен запускаться функцией создания процесса со специальным значением параметра флагов, а именно этот параметр должен задаваться символической константой EXEC_ASYNCRESULT. Если требуется ожидание только самого момента завершения, то достаточно использовать константу EXEC_ASYNC.

Для задания собственно ожидания завершения процесса в этой ОС предназначена функция с прототипом

APIRET DosWaitChild(ULONG action, ULONG option,

RESULTCODES *pres, PID *ppid, PID pid),

где параметр action задает чего именно требуется ожидать – завершения лишь одного процесса (задается константой DCWA_PROCESS) или завершения всей совокупности процессов-потомков, начиная с указанного процесса (задается константой DCWA_PROCESSTREE). Параметр option определяет режим выполнения данной функции и может задаваться константами DCWW_WAIT и DCWW_NOWAIT. Первая из них задает действительное ожидание, а вторая требует опросить состояние завершения и немедленно вернуть информацию об этом, не блокируя выполнение текущего процесса. Последний параметр pid задает идентификатор процесса, завершение которого требуется ожидать (или всех его потомков при задании соответствующего параметра action). Если значение этого параметра pid задается равным нулю, то это является указанием ожидать завершения любого дочернего процесса. Возвращаемый параметр ppid используется для получения значения идентификатора того процесса-потомка, который завершился последним при ожидании завершения всех потомков некоторого дочернего процесса или того дочернего процесса, который завершился после вызова функции с параметром pid, равным нулю.

Значение кода возврата, возвращаемое от завершенного процесса после выполнения рассматриваемой функции, находится в поле codeResult возвращаемого экземпляра pres структуры RESULTCODES. При этом поле codeTerminate этого возвращаемого параметра дает информацию о качественной причине завершения процесса. Эти причины описываются символическими константами и отображают как нормальное завершение, так и завершение по причине уничтожения другим процессом.

 

В операционной системе Unix имеется ранний вариант функции ожидания wait() с прототипом

pid_t wait(int *status).

Эта функция переводит текущий процесс в состояние ожидания до тех пор, пока не завершится какой-то из его дочерних процессов. Код возврата этого дочернего процесса получается функцией посредством параметра status. Если было запущено несколько дочерних процессов и необходимо дождаться завершения всех их, следует сделать соответствующее число вызовов функцией wait(), в частности, записав ее несколько раз подряд. Практически этой функцией удобно пользоваться при работе только с одним дочерним процессом. Поэтому в более поздних версиях Unix появилась дополнительная функция ожидания

pid_t waitpid(pid_t pid, int *status, int option),

которая позволяет задать с помощью значения pid завершение какого именно процесса будет ждать данный процесс, выполняющий функцию waitpid(), а параметром option - блокирующим или нет будет вызов функции. Использование этой функции требует включение заголовочного файла директивой #include <sys/wait.h>. Использование константы WNOHANG из этого файла в качестве параметра option обеспечивает немедленное возвращение функцией waitpid значения 0, если запращиваемый процесс еще не завершен. При нулевом значении этого параметра обеспечивается ожидание завершения процесса.

Следующая программа, приведенная в листинге 7.4.1, является исходным текстом для исполняемого файла procesw.exe, предназначенного для Unix. Для ее использования необходимо в автоматически доступном каталоге (в частности текущем) иметь исполняемый файл child1.exe, созданной из исходной программы, приведенной в листинге 7.3.1b.

#include <stdio.h>

#include <sys/types.h>

#include <signal.h>

int main()

{int rc, k;

printf("Parent Proccess\n");

rc=fork();

if (!rc) {execl("child1.exe",0); }

printf("For Child Process: PID=%d \n", rc);

wait(&rc);

printf("I have waited my child with retcode =%d\n",rc);

for (k=0; k<10; k++)

{printf("I am Parent (My K=%d)\n", k);

usleep(2000000);

}

printf("Parent ended\n"); exit(0);

}

Листинг 7.4.1. Программа procesw.c для Unix

 

В этой программе – после создания дочернего процесса и выдачи учетной информации о нем (идентификатора процесса PID) – вызывается функция wait() для ожидания завершения дочернего процесса. Наблюдение за поведением процессов, образующихся при запуске этой программы, позволяет явно видеть, что после выполнения wait() и до завершения дочернего процесса родительский приостановлен и продолжает работу только после завершения дочернего.

В операционных системах Windows для ожидания завершения процесса применяется универсальная функция ожидания WaitForSingleObject, имеющая прототип

DWORD WaitForSingleObject(HANDLE hProcess, DWORD Timeout).

Здесь первый параметр задает хэндл того процесса, завершения которого следует ждать, а второй параметр – максимальное время ожидания в миллисекундах. Если величину Timeout задать символической константой INFINITE, то ожидание неограниченно. В других случаях после истечения времени, заданного в Timeout, функция возвращает управление со значением самой функции, равным символической константе WAIT_TIMEOUT, по которой программа может определить, что ожидание было неудачным.

При удачном завершении ожидания можно получить код завершения дочернего процесса. Для его получения служит функция GetExitCodeProcess() с прототипом

BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD pExitCode).

Следующая программа, приведенная в листинге 7.4.2, является исходным текстом для исполняемого файла Procesw.exe, предназначенного для Windows. Для ее использования необходимо в автоматически доступном каталоге (в частности текущем) иметь исполняемый файл Child1.exe, действия которого аналогичны программе из листинга 7.3.1b, но предназначеного для Windows.

 

#include <windows.h>

#include <stdio.h>

int main()

{int k;

DWORD rc;

DWORD CreationFlags;

STARTUPINFO si;

PROCESS_INFORMATION pi;

 

printf("Demonstration processes, Main Proccess\n");

memset(&si, 0, sizeof(STARTUPINFO));

si.cb=sizeof(si);

CreationFlags = NORMAL_PRIORITY_CLASS;

 

rc=CreateProcess(NULL, "child1.exe", NULL, NULL, FALSE,

CreationFlags, NULL, NULL, &si, &pi);

if (!rc)

{printf("Error create Process, codeError = %ld\n", GetLastError());

getchar();

return 0;

}

printf("For Child Process:\n");

printf("hProcess=%d hThread=%d ProcessId=%lu ThreadId=%lu\n",

pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId);

WaitForSingleObject(pi.hProcess, INFINITE);

printf("It terminated child with hProcess\n", pi.hProcess);

GetExitCodeProcess(pi.hProcess, &rc);

printf("ExitCodeProcess=%ld\n", rc);

for (k=0; k<10; k++)

{printf("I am Parent... (my K=%d)\n", k);

Sleep(2000);

}

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

return 0;

}

Листинг 7.4.2. Программа Parentw.c для Windows

 

В этой программе – после создания дочернего процесса и выдачи учетной информации о нем (идентификатора в pi.hProcess) – вызывается функцию WaitForSingleObject ( pi.hProcess, INFINITE ) для ожидания завершения дочернего процесса, сколько бы долго он не длился. Получение информации о завершении процесса выполняется функцией GetExitCodeProcess(pi.hProcess, &rc).

Наблюдение за поведением процессов, образующихся при запуске этой программы, позволяет явно видеть, что после задания ожидания и до завершения дочернего процесса родительский приостановлен, он продолжает работу только после завершения дочернего.

 

<== предыдущая лекция | следующая лекция ==>
Уничтожение процессов | Понятие нити и связь Хе с процессом
Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 1536; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.027 сек.