URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1331
[ Назад ]

Исходное сообщение
"выход из child-процесса, не оставляя 'зомби' ?"

Отправлено dek , 30-Янв-03 16:37 
Программа, по приходу команд из сокета, создает - fork() - обрабатывающие их процессы, которые должны работать параллельно. В конце обрабатывающего (child) процесса находится функция exit(). В результате, по окончании child-процесса  остается процесс-"зомби". Чтобы не было такого ("зомби") в предок надо включать функцию wait(). Но мне не надо, чтобы предок ожидал окончания child-процесса, процессы должны порождаться независимо друг от друга, по приходу нужной информации. Кто может подсказать как прекращать child-процессы, не оставляя записей в таблице процессов (в смысле "зомби"-процессов)?

Заранее благодарен.


Содержание

Сообщения в этом обсуждении
"RE: выход из child-процесса, не оставляя 'зомби' ?"
Отправлено kalinin_den , 30-Янв-03 18:01 
Ловишь сигнал, который сообщает, что порожденный процесс завершился, и вызываешь wait(0), он ждать уже не будет:

void sig_hdlr(int signo)
{
  signal(SIGCHLD, sig_hdlr);

  if (signo == SIGCHLD)
    wait(0);

  ...
}

void main()
{
  signal(SIGCHLD, sig_hdlr);
  ...
}


"RE: выход из child-процесса, не оставляя 'зомби' ?"
Отправлено Soldier , 30-Янв-03 18:12 
>Ловишь сигнал, который сообщает, что порожденный процесс завершился, и вызываешь wait(0), он
>ждать уже не будет:
>
>void sig_hdlr(int signo)
>{
>  signal(SIGCHLD, sig_hdlr);
>
>  if (signo == SIGCHLD)
>    wait(0);
>
>  ...
>}
>
>void main()
>{
>  signal(SIGCHLD, sig_hdlr);
>  ...
>}

В данном случае достаточно просто

signal(SIGCHLD, SIG_IGN);

То бишь просто игнорировать сигнал безо всяких дополнительных заморочек.



"RE: выход из child-процесса, не оставляя 'зомби' ?"
Отправлено dek , 30-Янв-03 18:47 
Большое спасибо.

"RE: выход из child-процесса, не оставляя 'зомби' ?"
Отправлено romanSA , 31-Янв-03 10:09 
>>Ловишь сигнал, который сообщает, что порожденный процесс завершился, и вызываешь wait(0), он
>>ждать уже не будет:
>>
>>void sig_hdlr(int signo)
>>{
>>  signal(SIGCHLD, sig_hdlr);
>>
>>  if (signo == SIGCHLD)
>>    wait(0);
>>
>>  ...
>>}
>>
>>void main()
>>{
>>  signal(SIGCHLD, sig_hdlr);
>>  ...
>>}
>
>В данном случае достаточно просто
>
>signal(SIGCHLD, SIG_IGN);
>
>То бишь просто игнорировать сигнал безо всяких дополнительных заморочек.

Ну это не совсем так. Ибо...
1) По требованиям стандартов POSIX нельзя устанавливать обработчик сигнала SIGCHLD в SIG_IGN. И это нужно учесть, так как все *NIX системы стараются как можно больше соответветствовать этим стандартам.
2) Не рекомендую использовать wait() для ожидания смерти процессов в обработчике, так как возможна ситуация, когда при завершении работы _нескольких_ дочерних процессов, родитель получит только _один_ сигнал.
"Правильный" способ ожидания завершения процессов следующий:

void SIGCHLD_handler (int nSignal)
{
   int nPid;
   signal (nSignal, SIGCHLD_handler);
   while ((nPid = wait3 (NULL, WNOHANG, (struct rusage *) NULL)) > 0);  
}

Дополнительно, см. man 2 wait3


"RE: выход из child-процесса, не оставляя 'зомби' ?"
Отправлено Soldier , 31-Янв-03 15:27 
>Ну это не совсем так. Ибо...
>1) По требованиям стандартов POSIX нельзя устанавливать обработчик сигнала SIGCHLD в SIG_IGN.
>И это нужно учесть, так как все *NIX системы стараются как
>можно больше соответветствовать этим стандартам.
>2) Не рекомендую использовать wait() для ожидания смерти процессов в обработчике, так
>как возможна ситуация, когда при завершении работы _нескольких_ дочерних процессов, родитель
>получит только _один_ сигнал.
>"Правильный" способ ожидания завершения процессов следующий:
>
>void SIGCHLD_handler (int nSignal)
>{
>   int nPid;
>   signal (nSignal, SIGCHLD_handler);
>   while ((nPid = wait3 (NULL, WNOHANG, (struct rusage *) NULL)) > 0);  
>}
>
>Дополнительно, см. man 2 wait3

Спасибо за лекцию (искренне). Но я на 99.9999....%  уверен (ибо на 100% может быть уверен только господь Бог, аминь :)))), что в конкретно данном случае (запуск детей в свободное плавание) можно обойтись и "неправильным" способом и все будет OK. Хотя конечно несоответствие стандартам POSIX это страшшшное преступление... :)))