LINUX.ORG.RU

Синхронизация процессов при fork()


0

0

Есть родительский процесс, который следит за неким множеством дочерних процессов. На каждый дочерний процесс у родителя есть некий набор информации. Нужно отловить момент завершения дочернего процесса.

Сейчас я ставлю обработчик SIGCHLD, смотрю на pid завершившегося процесса и нахожу доп. инфу о процессе в списке дочерних процессов. Вся проблема в том, что если дочерний процесс очень быстро закончится, то его код сохранения pid'а в таблице (т.е. кусок сразу после fork) будет выполнен после обработчика SIGCHLD, который соответственно не найдет инфы в таблице.

Как лечить?

Re: Синхронизация процессов при fork()

Если делаете exec - тогда man vfork. И заполнить таблицу в дочернем процессе до exec.

svu ★★★★★ ()

Re: Синхронизация процессов при fork()

Отделить обработчик sigchld и логику, которую в него запихал? Обработчик будет ловить умерших детей и ложить в queue. Логика будет время от времени выгребать pid'ы из этого queue.

mv ★★★★★ ()

Re: Синхронизация процессов при fork()

слип после форка в дочке ?
дабы родитель успел произвести все препарации...

а вобще если ваш форк отрабатывает так быстро
это наводит на мысль что он не нужен
и дизайн который вы задумали крив до безобразия

anonymous ()
Ответ на: Re: Синхронизация процессов при fork() от anonymous

Re: Синхронизация процессов при fork()

>слип после форка в дочке ? дабы родитель успел произвeсти все препарации...

потенциальный race, перед форком маскировать обработку сигналов. ИМХО, это более правильно. И pid потомка можно занести в структуру и в протомке первым делом переопределить обработчики сигналов (если надо).

P.S. 2generatorglukoff. Надеюсь, что после получения сигнала SIGCHLD wait() вызывается в цикле с флагом WNOHANG пока wait() не вернет -1, так как не гарантируется доставка SIGCHLD на каждый порожденный процесс...

mky ★★★★★ ()
Ответ на: Re: Синхронизация процессов при fork() от mky

Re: Синхронизация процессов при fork()

Крвовато написал. То есть "слип после форка в дочке" --- это потенциальный race condition. Так как в случае большой нагрузки (большого количества выполняемых процессов) не гарантируется время, через которое родительский процесс продолжит свое выполнение). Лучше всего маскировать сигналы (для простоты кода можно маскировать все сигналы) перед вызовом fork().

mky ★★★★★ ()

Re: Синхронизация процессов при fork()

Ждёшь завершения с помощью waitpid, а потом обрабатываешь код завершения и дальше ждёшь.

grishkin ()

Re: Синхронизация процессов при fork()

Нити, семафоры и мьютексы уже не кашерно?

marsijanin ★★ ()

Re: Синхронизация процессов при fork()

> Как лечить?

лоботомией

anonymous ()

Re: ????????????? ????????? ??? fork()

clone(CLONE_PARENT_SETTID, ptr_to_the_child_pid) instead of fork(), or

sigprocmask(SIG_BLOCK, {SIGCHLD});
pid = fork();
add_to_database(pid);
sigprocmask(SIG_UNBLOCK, {SIGCHLD});

idle ★★★★★ ()
Ответ на: Re: ????????????? ????????? ??? fork() от idle

Re: ????????????? ????????? ??? fork()

> sigprocmask(SIG_BLOCK, {SIGCHLD}); pid = fork(); add_to_database(pid); sigprocmask(SIG_UNBLOCK, {SIGCHLD});

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

dilmah ★★★★★ ()

Re: Синхронизация процессов при fork()

Зачем эти сигналы нужны? Можно ведь просто использовать waitpid?

smh ★★★ ()
Ответ на: Re: ????????????? ????????? ??? fork() от dilmah

Re: ????????????? ????????? ??? fork()

surely the blocked SIGCHLD can't prevent the child
from exiting. but it blocks the signal until the
parent adds the pid to its internal database.

this means that the signal handler won't be confused
seeing the unregistered pid.

idle ★★★★★ ()

Re: Синхронизация процессов при fork()

> Сейчас я ставлю обработчик SIGCHLD, смотрю на pid завершившегося процесса и нахожу доп. инфу (...)

Основная ошибка: этого _нельзя_ делать в обработчике SIGCHLD. Там можно выставить флажок "нам помахали SIGCHLD'ом" и всё. Сдохший потомок будет висеть зомбяком до тех пор пока родитель не удосужится поинтересоваться его статусом через waitpid. А до вызова waitpid можно заполнить все необходимые таблицы и т.д.

anonymous ()

Re: Синхронизация процессов при fork()

Ребенок сам может добавить себя в базу, получив свой номер из getpid(). Дочерний процесс точно не умрет, до того как зарегистрируется. Только не забудте про синхронизацию доступа к базе детей.

anonymous ()

Re: Синхронизация процессов при fork()

2mv: я развил эту идею. Достаточно одного флажка "процесс умер, но инфы о нем записано еще не было", т.к. в один момент времени может быть не более одного такого процесса (т.е. об остальных процессах инфа точно есть). После форка проверяется состояние этого флажка и в случае необходимости вызывается логика обработки завершения (такая же, как и при SIGCHLD).

2mky: спасибо за цикл. Ибо в манах ничего не написано (ну или я совсем ослеп), что SIGCHLD может и не прийти.

PS. Вобщем-то [Solved]

generatorglukoff ★★ ()
Ответ на: Re: Синхронизация процессов при fork() от generatorglukoff

Re: Синхронизация процессов при fork()

>После форка проверяется состояние этого флажка и в случае необходимости вызывается логика обработки завершения (такая же, как и при SIGCHLD).

Как засинхронизировал добавление учетной информации о ребенке в потоке с форком и его чтение/удаление в обработчике сигнала? Здесь точно не подходят обычные мутексы, так как возможен деадлок... Вариант mky и idle с временным блокированием сигнала идеален во всех отношениях.

anonymous ()
Ответ на: Re: Синхронизация процессов при fork() от anonymous

Re: Синхронизация процессов при fork()

>Как засинхронизировал добавление учетной информации о ребенке в потоке с форком и его чтение/удаление в обработчике сигнала?

Форк происходит в том же потоке, что и обработчик сигнала. В обработчике сигнала есть две ситуации: вся инфа записана (а поле pid'а заполняется последним) либо нет (т.е. в списке не нашли инфу к процессу с таким pid'ом).

generatorglukoff ★★ ()
Ответ на: Re: Синхронизация процессов при fork() от generatorglukoff

Re: Синхронизация процессов при fork()

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

anonymous ()
Ответ на: Re: Синхронизация процессов при fork() от anonymous

Re: Синхронизация процессов при fork()

>В противном случае после форка только найдете место в списке куда добавить, в этот момент доходит сигнал и обработчик удаляет из списка все завершенные процессы, структура бызы полностью меняется, после возвращения из сигнала запишите по невалидному адресу.

Для обхода этой ситуации у меня в списке есть пустые элементы, куда можно записать информацию. Таким образом, при удалении информации структура базы не меняется, только при добавлении в отсутствии свободных мест. Платой этому есть некоторый расход памяти на простаивающие элементы, но это совсем копейки.

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