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

Идентификатор процесса


Как уже отмечено в начале этой главы, система присваивает каждому процессу неотрицательное число, которое называется идентификатором процесса. В любой момент времени идентификатор процесса является уникальным, хотя после завершения процесса он может использоваться снова для другого процесса. Некоторые идентификаторы процесса зарезервированы системой для особых процессов. Процесс с идентификатором 0, хотя он и называется планировщиком (scheduler), на самом деле является процессом подкачки памяти (swapper). Процесс с идентификатором 1 – это процесс инициализации, выполняющий программу /etc/init. Этот процесс, явно или неявно, является предком всех других процессов в системе UNIX.

Программа может получить свой идентификатор процесса при помощи следующего системного вызова:

pid := getpid;

Аналогично вызов getppid возвращает идентификатор родителя вызывающего процесса:

ppid := getppid;

Например:

Uses linux;

begin

  Writeln ('Process Id = ',getpid,' Parent process Id = ',getppid);

end.

Следующая процедура gentemp использует вызов getpid для формирования уникального имени временного файла. Это имя имеет форму:

/tmp/tmp<pid>.<no>

Суффикс номера <nо> увеличивается на единицу при каждом вызове процедуры gentemp. Процедура также вызывает функцию access, чтобы убедиться, что файл еще не существует:



uses linux,strings;

const

  num:integer=0;

  namebuf:array [0..19] of char='';

  prefix='/tmp/tmp';

function gentemp:pchar;

var

  length:integer;

  pid:longint;

begin

  pid := getpid;       (* получить идентификатор процесса *)

  (* Стандартные процедуры работы со строками *)

  strcopy (namebuf, prefix);

  length := strlen (namebuf);

  (* Добавить к имени файла идентификатор процесса *)

  itoa (pid, @namebuf[length]);

  strcat (namebuf, '.');

  length := strlen (namebuf);

  repeat

    (* Добавить суффикс с номером *)

    itoa(num, @namebuf[length]);

    inc(num);

  until(not access (namebuf, F_OK));




  gentemp:=namebuf;

end;

Процедура itoa просто преобразует целое число в эквивалентную строку:

 (* Функция itoa - преобразует целое число в строку *)

function itoa(i:integer;str:pchar):integer;

var

  power, j : integer;

begin

  j := i;

  power := 1;

  while j >= 10 do

  begin

    power := power * 10;

    j := j div 10;

  end;

  while power > 0 do

  begin

    str^ := char(byte('0') + i div power);

    inc(str);

    i := i mod power;

    power := power div 10;

  end;

  str^ := #0;

end;

Обратите внимание на способ преобразования цифры в ее символьный эквивалент в первом операторе во втором цикле for – он опирается на знание таблицы символов ASCII. Следует также отметить, что большую часть работы можно было бы выполнить гораздо проще при помощи процедуры sprintf. Описание процедуры sprintf смотрите в главе 11.

Упражнение 5.11. Переделайте процедуру gentemp так, чтобы она принимала в качестве аргумента префикс имени временного файла.


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