Системное программирование в UNIX средствами Free Pascal

       

Совместное использование вызовов ехес и fork


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

 (* Программа runls3 - выполнить ls как субпроцесс *)

uses linux,stdio;

var

  pid:longint;

begin

  pid := fork;

  case pid of

    -1:

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

    0:

    begin

      (* Потомок вызывает exec *)



      execl('/bin/ls -l');

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

    end;

    else

    begin

      (* Родительский процесс вызывает wait для приостановки

       * работы до завершения дочернего процесса.

       *)

      wait(nil);

      writeln('Программа ls завершилась');

      halt(0);

    end;

  end;

end.

Процедура fatal использует функцию perror для вывода сообщения, а затем завершает работу процесса. Процедура fatal реализована следующим образом:

procedure fatal(s:pchar);

begin

  perror(s);

  halt(1);

end;

Снова графическое представление, в данном случае рис. 5.4, используется для наглядного объяснения работы программы. Рисунок разбит на три части: До вызова fork, После вызова fork и После вызова ехес.

В начальном состоянии, До вызова fork, существует единственный процесс А

и программный счетчик

PC направлен на оператор fork, показывая, что это следующий оператор, который должен быть выполнен.

После вызова fork существует два процесса, А

и В. Родительский процесс A выполняет системный вызов wait. Это приведет к приостановке выполнения процесса А до тех пор, пока процесс В не завершится. В это время процесс В использует вызов execl для запуска на выполнение команды ls.

pid:=fork;

< PC

A

До вызова fork

wait(nil);

< PC

execl('/bin/ls -l');

< PC

A

B

После вызова fork

После вызова exec

(* 1-ая строка ls*)

< PC

wait(nil);

< PC

A

B (теперь

выполняет команду ls)

Рис. 5.4. Совместное использование вызовов fork и ехес

Что происходит дальше, показано в части После вызова ехес на рис. 5.4. Процесс В

изменился и теперь выполняет программу ls. Программный счетчик процесса В установлен на первый оператор команды ls. Так как процесс А

ожидает завершения процесса В, то положение его программного счетчика PC не изменилось.

Теперь можно увидеть в общих чертах механизмы, используемые командным интерпретатором. Например, при обычном выполнении команды оболочка использует вызовы fork, ехес и wait приведенным выше образом. При фоновом исполнении команды вызов wait пропускается, и оба процесса – команда и оболочка – продолжают выполняться одновременно.



Содержание раздела