Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

5.7.2. Ожидание завершения определенного потомка: вызов waitpid

Системный вызов wait позволяет родительскому процессу ожидать завершения любого дочернего процесса. Тем не менее, если нужна большая определенность, то можно использовать системный вызов waitpid для ожидания завершения определенного дочернего процесса.

Описание

uses linux;

Function WaitPid(Pid:longint; Status:pointer; Options:Longint):Longint;

Первый аргумент pid определяет идентификатор дочернего процесса, завершения которого будет ожидать родительский процесс. Если этот аргумент установлен равным -1, а аргумент options установлен равным 0, то вызов waitpid ведет себя в точности так же, как и вызов wait, поскольку значение -1 соответствует любому дочернему процессу. Если значение pid больше нуля, то родительский процесс будет ждать завершения дочернего процесса с идентификатором процесса равным pid. Во втором аргументе status будет находиться статус дочернего процесса после возврата из вызова waitpid.

Последний аргумент, options, может принимать константные значения, определенные в модуле linux. Наиболее полезное из них – константа WNOHANG. Задание этого значения позволяет вызывать waitpid в цикле без блокирования процесса, контролируя ситуацию, пока дочерний процесс продолжает выполняться. Если установлен флаг WNOHANG, то вызов waitpid будет возвращать 0 в случае, если дочерний процесс еще не завершился.

Функциональные возможности вызова waitpid с параметром WNOHANG можно продемонстрировать, переписав предыдущий пример. На этот раз родительски процесс проверяет, завершился ли уже дочерний процесс. Если нет, он выводит сообщение, говорящее о том, что он продолжает ждать, затем делает секундную паузу и снова вызывает waitpid, проверяя, завершился ли дочерний процесс. Обратите внимание, что потомок получает свой идентификатор процесса при помощи вызова getpid. Об этом вызове расскажем в разделе 5.10.1.

(* Программа status2 - получение статуса завершения

* дочернего процесса при помощи вызова waitpid

*)

uses linux,stdio,crt;

var

pid:longint;

status, exit_status:integer;

begin

pid := fork;

if pid < 0 then

fatal ('Ошибка вызова fork ');

if pid = 0 then (* потомок *)

begin

(* Вызов библиотечной процедуры sleep

* для приостановки выполнения на 4 секунды

*)

writeln ('Потомок ',getpid,' пауза...');

sleep(4);

halt(5); (* выход с ненулевым значением *)

end;

(* Если мы оказались здесь, то это родительский процесс *)

(* Проверить, закончился ли дочерний процесс, и если нет, *)

(* то сделать секундную паузу, и потом проверить снова *)

while (waitpid (pid, @status, WNOHANG) = 0) do

begin

writeln ('Ожидание продолжается...\n');

sleep(1);

end;

(* Проверка статуса завершения дочернего процесса *)

if WIFEXITED (status) then

begin

exit_status := WEXITSTATUS (status);

writeln ('Статус завершения ',pid,' равен ', exit_status);

end;

halt(0);

end.

При запуске программы получим следующий вывод:

Ожидание продолжается...

Потомок 12857 пауза...

Ожидание продолжается...

Ожидание продолжается...

Ожидание продолжается...

Статус завершения 12857 равен 5

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal