Хрестоматия по программированию на Си в Unix



Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 10


Вот схема, поясняющая жизненный цикл любого процесса:

|pid=719,csh

| if(!fork())------->--------* pid=723,csh

| | загрузить wait(&status) exec("a.out",...) <-- a.out

: main(...){ с диска : | :pid=719,csh | pid=723,a.out

спит(ждет) работает : | : exit(status) умер : } проснулся <---проснись!--RIP | |pid=719,csh

Заметьте, что номер порожденного процесса не обязан быть следующим за номером родителя, а только больше него. Это связано с тем, что другие процессы могли создать в системе новые процессы до того, как наш процесс издал свой вызов fork.

6.5.7. Кроме того, wait позволяет отслеживать остановку процесса. Процесс может быть приостановлен при помощи посылки ему сигналов SIGSTOP, SIGTTIN, SIGTTOU, SIGTSTP. Последние три сигнала посылает при определенных обстоятельствах драйвер терминала, к примеру SIGTSTP - при нажатии клавиши CTRL/Z. Продолжается процесс посылкой ему сигнала SIGCONT.

В данном контексте, однако, нас интересуют не сами эти сигналы, а другая схема манипуляции с отслеживанием статуса порожденных процессов. Если указано явно, система может посылать процессу-родителю сигнал SIGCLD в момент изменения статуса любого из его потомков. Это позволит процессу-родителю немедленно сделать wait и немедленно отразить изменение состояние процесса-потомка в своих внутренних списках. Данная схема программируется так:

void pchild(){ int pid, status;

sighold(SIGCLD); while((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0){ dorecord: записать_информацию_об_изменениях; } sigrelse(SIGCLD);

/* Reset */ signal(SIGCLD, pchild); } ... main(){ ... /* По сигналу SIGCLD вызывать функцию pchild */ signal(SIGCLD, pchild); ... главный_цикл; }

Секция с вызовом waitpid (разновидность вызова wait), прикрыта парой функций sighold-sigrelse, запрещающих приход сигнала SIGCLD внутри этой критической секции. Сделано это вот для чего: если процесс начнет модифицировать таблицы или списки в районе метки dorecord:, а в этот момент придет еще один сигнал, то функция pchild




Содержание  Назад  Вперед