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

6.4.3. Системный вызов pause

ОС UNIX также содержит дополняющий вызов alarm системный вызов pause, который определен следующим образом:

Описание

uses linux;

Procedure Pause;

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

Следующая программа tml (сокращение от «tell me later» – напомнить позднее) использует оба вызова alarm и pause для вывода сообщения в течение заданного числа минут. Она вызывается следующим образом:

$ tml число_минут текст_сообщения

Например:

$ tml 10 время идти домой

Перед сообщением выводятся три символа Ctrl+G (звуковые сигналы) для привлечения внимания пользователя. Обратите внимание на создание в программе tml фонового процесса при помощи вызова fork. Фоновый процесс выполняет работу, позволяя пользователю продолжать выполнение других задач.

(* tml - программа для напоминания *)

{$mode objfpc}

uses linux, stdio, sysutils;

const

BELLS=#7#7#7; (* звуковой сигнал ASCII *)

alarm_flag:boolean = FALSE;

(* Обработчик сигнала SIGALRM *)

procedure setflag(sig:integer);cdecl;

begin

alarm_flag := TRUE;

end;

var

nsecs, j:integer;

pid:longint;

act:sigactionrec;

begin

if paramcount < 2 then

begin

writeln (stderr, 'Применение: tml число_минут сообщение');

halt(1);

end;

try

nsecs := strtoint(paramstr(1)) * 60;

except

on e:econverterror do

begin

writeln (stderr, 'Введено нечисловое значение');

halt(2);

end;

end;

if nsecs <= 0 then

begin

writeln (stderr, 'tml: недопустимое время');

halt(3);

end;

(* Вызов fork, создающий фоновый процесс *)

pid := fork;

case pid of

-1: (* ошибка *)

begin

perror ('tml');

halt(1);

end;

0: (* дочерний процесс *)

;

else (* родительский процесс *)

begin

writeln('Процесс tml с идентификатором ', pid);

halt(0);

end;

end;

(* Установить обработчик таймера *)

act.handler.sh := @setflag;

sigaction (SIGALRM, @act, nil);

(* Установить таймер *)

alarm (nsecs);

(* Приостановить выполнение до получения сигнала ... *)

pause;

(* Если был получен сигнал SIGALRM, вывести сообщение *)

if alarm_flag then

begin

write(BELLS);

for j := 2 to paramcount do

write(paramstr(j),' ');

writeln;

end;

halt(0);

end.

Из этого примера можно получить представление о том, как работает подпрограмма sleep, вызывая вначале alarm, а затем pause.

Упражнение 6.3. Напишите свою версию подпрограммы sleep. Она должна сохранить предыдущее состояние таймера и восстанавливать его при выходе. (Посмотрите полное описание процедуры sleep в справочном руководстве системы.)

Упражнение 6.4. Перепишите программу tml, используя свою версию процедуры sleep.

6.4.4. Системные вызовы sigpending и sigsuspend

ОС UNIX также содержит дополняющие вызов SigProcMask системные вызовы SigPending и SigPending, которые определены следующим образом:

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