Вызов 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.