LINUX.ORG.RU

wait и wait4


0

0

Родительский процесс должен отслеживать смерть
своих детей, для этого регистрирую обрабочик
для SIGCHLD

//function for catch SIGCHILD
void sig_child ( int sig_in)
{
	fprintf ( stderr, "\none child dead :))\n");
	child_count--;
	int status;
	wait4 ( &status);
};

но если умарает два потомка пока родитель не работает
то один из них превращается в зомби.

Попытался использовать вместо wait wait4, но он входит
в бесконечный цикл. 

//function for catch SIGCHILD
void sig_child ( int sig_in)
{
	fprintf ( stderr, "\none child dead :))\n");
	child_count--;
	int status;
	pid_t pid = -1;
	struct rusage rsg;
	while ( wait4 ( pid, &status, WNOHANG, &rsg))
	{
		child_count--;
		fprintf ( stderr, "\none child dead :))\n");
	};
};

Подскажите в чем моя ошибка и как
вообще решается такая проблема.
anonymous

Вопрос в догонку если у меня дети посылают сигнал usr1 и будет подобная ситуация, то как ее решить.

anonymous
()

void sig_child ( int sig_in)
{
        int status;
        while ( waitpid(-1,&status,WNOHANG)>0)
        {
                child_count--;
                fprintf ( stderr, "\none child dead :))\n");
        };
};

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Спасибо, но не пойму почему не работает ни оди мой вариант. Про первый wait забыл написать при регистрации обработчика указываю параметр SA_NODEFER, т.е. разрешаю прерывать обработчик таким же сигналом. Про второй вариант то же не пойму - почему не работает?

anonymous
()
Ответ на: комментарий от anonymous

Насколько я понимаю, для сохранения кол-ва сигналов недостаточно просто поставить SA_NODEFER. Только Real-Time сигналы дойдут в том количестве, что были посланы.

Если два НЕ rt сигнала пришли одновременно, обработчик будет вызван один раз, независимо от флага SA_NODEFER.

Второй вариант: (наверное; не уверен) вызов wait4 был перебит SIGCHILD и возвратил -1. Поскольку цикл в обработчике, то wait4 все время перебивается pending сигналом и возвращает -1.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

Т.е. SA_NODEFER и SA_NIMASK повлияют на обработку тольку rt сигналов, а остальные будут потеряны? Как вообще решается такая проблема?

anonymous
()
Ответ на: комментарий от anonymous

> Т.е. SA_NODEFER и SA_NIMASK повлияют на обработку тольку rt сигналов, а остальные будут потеряны?

Все. что я знаю -- если два не rt сигнала (с одним и тем же номером) приходят одновременно, то они "сливаются". В этом и состоит отличие от них rt сигналов: rt сигналы будут доставлены гарантированно, в том же количестве, в котором они были сгенерированы.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>Все. что я знаю -- если два не rt сигнала (с одним и тем же номером) приходят одновременно, то они "сливаются".

Обьяснить можешь как ето сливаются и как их потом разделять

cvv ★★★★★
()
Ответ на: комментарий от cvv

2cvv:

Могу только повторить в 3 раз :-)

Если одинаковые не rt сигналы пришли одновременно, то обработчик будет вызван только один раз.

Die-Hard ★★★★★
()
Ответ на: комментарий от cvv

>Обьяснить можешь как ето сливаются и как их потом разделять

Представь себе битовую маску sigpending, в которой выставляются биты, соответствующую pending сигналам. Если сумеешь из битовой маски выделить количество посланных сигналов, то значит зря придумывали (и реализовывали) POSIX сигналы. :)

Murr ★★
()
Ответ на: комментарий от cvv

> Обьяснить можешь как ето сливаются и как их потом разделять

кто-то посылает твоему процессу сигналы, что по сути всего навсего установка соответстующих битов в наботе флагов в ядрёной структуре, асоциированной с твоим процессом. при переходе процесса из kernel space в user space проверяются эти биты. если они взедены производятся действия установленные sigaction для соответствующих сигналов. В частности выполняется exit для 9. Приход сигнала будит процесс если он спал, точнее если был в TASK_INTERRUPTIBLE. но не факт что он будет запущен, на всё воля schedule

anonymous
()

спасибо чтото прояснилось

cvv ★★★★★
()
Ответ на: комментарий от anonymous

Т.е. я так понял что даже использование SA_NODEFER не гарантирует боработку двух сигналов. Придется пользоваться shmget и иже с ним. Просто сервер почти готов и вот не этапе тестирования обнаружил что появляются зомби, при анализе обнаружил потерю сигнала и как следствие потеря одного из процессов, т.к. не происходит child_count--.

Спасибо за обсуждение.

Stalcker.

anonymous
()
Ответ на: комментарий от anonymous

если мне ничего не изменяет то игнорирование SIGHLD приведёт к тому что дети будут помирать полностью, как бы без зомби. разумеется в таком раскладе не получишь возвращаемого значения

anonymous
()
Ответ на: комментарий от anonymous

2Stalcker:

> ...при анализе обнаружил потерю сигнала и как следствие потеря одного из процессов, т.к. не происходит child_count--.

В том коде, что я привел, child_count будет правильным, и зомби не будет.

Die-Hard ★★★★★
()
Ответ на: комментарий от anonymous

anonymous (27.01.2005 19:17:16):

>... игнорирование SIGHLD приведёт к тому что дети будут помирать полностью, как бы без зомби.

Там расхождение сильное в спецификациях POSIX и POSIX 1003.1-2001. А Линух вообще по-своему поступает. Все написано в man 2 wait.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>В том коде, что я привел, child_count будет правильным, и зомби не будет.

Да, спасибо за подсказку, проблемма с зомби решена. Просто еще использовались сигналы usr1 i usr2 для уведомления основного процесса о том, что в одном из дочерних процессов все потоки ужуе заняты и необходимо порождать еще один процесс, теперь для этого использую расшаренную память.

stalcker
()
Ответ на: комментарий от stalcker

stalcker (28.01.2005 11:16:28):

> Просто еще использовались сигналы usr1 i usr2 для уведомления основного процесса...

Для подобных случаев и придуманы rt сигналы. Используй их, они будут доставлены гарантированно.

Я в подобных случаях (для сигналов от дочек к папе) прокидываю пайпы, и смотрю их из папы селектом. Конечно, присущей сигналам асинхронности при этом не получить, но она и не нужна по логике клиент-серверной hub-and-spoke парадигмы: сервер должен заниматься обслуживанием клиентов. Если надо делать что-то еще, сервер должен отфоркнуть специальную дочку.

Die-Hard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.