Перейти к содержанию

О взаимодействии родственных процессов


Гость

Рекомендуемые сообщения

Ситуация следующая: есть два процесса - ребенок и родитель. Родитель передает ребенку данные, синхронизация между ними сделана с помощью сигналов, т.е. родитель ждет от ребенка сигнала готовности принять новую порцию, а ребенок, просигналив о готовности, ждет сигнала окончания передачи.

Вопрос: Родитель получает сигнал от ребенка и, не отправив сигнала о конце передачи, трагически погибает. Естественно, ребенок при этом остается в состоянии ожидания навечно.

Может ли как-нибудь процесс-ребенок проверить, жив ли его родитель, или получить сигнал связанный с его смертью?

Ссылка на комментарий
Поделиться на другие сайты

Есть куча видов IPC:

* Полудуплексные каналы UNIX

* FIFO (именованные каналы)

* Очереди сообщений в стиле SYSV

* Множества семафоров в стиле SYSV

* Разделяемые сегменты памяти в стиле SYSV

* Сетевые сокеты (в стиле Berkeley)

* Полнодуплексные каналы (каналы потоков)

(см. Linux Programmer's Guide, Scott Burkett)

Может синхронизировать это по каналам? Скажем, ребенок изредка спрашивает родителя: "Чувак, ты еще жив?", на что родитель должен ответить: "Да живая я, спокуха!" =)

Ну или отслеживать Process ID.

Ссылка на комментарий
Поделиться на другие сайты

К сожалению, это не просто моя программа для собственных нужд, а задача по информатике, где нельзя использовать ничего кроме сигналов.

Я уже начинаю думать, что мое решение по определению страдает эти пороком. Понимаете, после того как родитель сообщил, что он жив, ребенок может на какое-то время потерять процессор, а родитель в этот промежуток умрет. Ребенок, уверенный, что предок жив, быдет жжать от него сигнала вечно. Проверка на живость и переход в ожидание сигнала от родителя не атомарная операция.

Можно ли организовать что-то типа семафора с помощью сигналов?

Ссылка на комментарий
Поделиться на другие сайты

Самый простой и логичный способ - использовать сокеты или следить за PID-ом. Можно сделать двухпоточного ребенка, где один поток следит за PID-ом родителя (getppid() в цикле), а другой ждет сигнала. Если родитель помер, первый сам посылает второму какой-нибудь сигнал, раз уж надо его разбудить. =) То же самое с сокетами.

Еще есть функция atexit() (см. man), но она работает только при нормальном завершении, при сигнале KILL и т.п. она не выполнится. А еще, по-моему, можно использовать select для синхронизации между процессами по pipe-ам.

Ссылка на комментарий
Поделиться на другие сайты

А что происходит, когда процесс ждет сигнала от init?

Просто добавил такую проверку:

for (i=0; i<8; i++) {

status = kill(ppid, SIGUSR1);

fprintf(stderr, "status - %d\n", status);

sleep(60); //чтобы убить родителя после удачной посылки сигнала

if (status < 0) {

fprintf(stderr, "Abort!");

exit(-1);

}

sigsuspend(&set);

//полезные действия

}

При этом как и положено сначала выводит status - 0. Уходит ждать. Я убиваю родителя.

А через минуту ребенок выводит status - -1, и завершает исполнение.

Похоже init как-то будит приемных детей. Так ли это?

Ссылка на комментарий
Поделиться на другие сайты

Извини за тормоза, но я попробовал, и у меня вроде все работает. Надо смотреть подробнее про init. По идее, он не должен слать сигналов приемным детям, так что будем думать. Если чего нароешь, пиши, самому интересно. А так - попробую завтра разобраться, чего найду - напишу. А почему нельзя использовать ничего, кроме сигналов? Условие задачи? Просто странно, есть куча альтернативных способов, которые гораздо удобнее...

Ссылка на комментарий
Поделиться на другие сайты

Цитата:

Извини за тормоза, но я попробовал, и у меня вроде все работает

Да ошибся я, когда убивал процесс-родитель. sleep надо в нем писать, а не в теле ребенка. init не посылает никаких сигналов. По крайней мере, насколько я накопал в этом направлении.

Цитата:

А почему нельзя использовать ничего, кроме сигналов?

Да, это задача по информатике на тему сигналы. На самом деле даже интересно. Теперь вот строим семафор на базе fifo...

Всем спасибо, нашел простое решение.

for (i=0; i<8; i++) {

alarm(1);

sigsuspend(&set);

alarm(0);

//полезные действия

}

А по SIGALARM прверяется pid родителя и, если он жив(т.е. наш родитель не init), то снова выставляется alarm(1).

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...