LINUX.ORG.RU

проблема с fork() в многопотоковом приложении


0

0

Ситуация: приложение имеет изначально два потока (main и еще один). ps дает информацию о 3 pid (третий - т.н. manager_thread). Приложение делает fork() в main, после завершения порожденого процесса умирает второй поток (порожденный в начале) и manager_thread становится defunct. Раньше такой проблемы не возникало.

Подкажите, чем может быть вызван такой баг?

anonymous

Ты бы для начала уточнил, что у тебя за платформа, используешь ли ты pthread, как ты реагируешь на SIGCHLD, чем твои треды занимаются (в смысле какой момент завершается твой "еще один" тред). После того, как все это разбирать начнешь, может и сам допетришь отчего не работает;)
В противном случае в твоей ситуации можно только гадать;)

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

По пунктам: Платформа два проца (P3) RH6.2 ядро 2.2.14 Да использую pthread На SIGCHLD я реагирую SIG_IGN Два моих треда занимаются тем, что первый из них является CORBA (TAO) сервером а второй рассылает входящие запросы на кучку клиентов после fork() создается еще пара тредов (для чтения и записи в пайпы потомка) вся эта ботва счастливо работает ровно до завершения потомка, после чего завершаются все треды кроме стартового а manager_thread уходит в дефанкт

в процессе долгих экспериментов было выяснено что этого не происходит если завершать потомка _exit либо abort

anonymous
()

Ага, понятно. попробуем по порядку.
1. Для начала не советую тебе пользоваться _exit(), используй лучше exit() и тогда будет исполняться код, который еще относится к процессу но болтается выше main(), т.е. библиотечный код. Короче, использовать _exit() - знак плохого тона, да и код, зарегистрированный через atexit(), в слечае _exit() не отрабатывает.
2. abort() тоже не советую использовать, т.к. заканчивать процесс нужно более изящно, нежели через abort().
3. Если ты не можешь обойтись без abort() и _exit() - что ж, тогда принимай поздравления. С огромной долей вероятности это сигнал к тому, что ты накосячил в архитектуре (не правильно спроектировал синхронизацию).
4. Вместо того, чтобы игнорировать SIGCHLD - лучше сообщи ядру, что тебя не интересует код возврата твоего потомка. Для этого после старта потомка нужно вызвать waitpid(child_pid, (int*)&child_status, WNOHANG).
5. старайся избегать "лишних" тредов - большое количество тредов только усугубляет положение.
6. если после того, как ты перестанешь использовать _exit(), abort() и будешь пользоваться waitpid() ситуация не изменится, тогда заведи тред sigcatcher, т.е. тред, который будет "слушать" приходящие на процесс сигналы с помощью sigwait() и реагировать на них по обстоятельствам. Это последний радикальный метод. Если он не поможет - ты будешь самым счастливым человеком на свете и, может быть задумаешься о том, что системные задачи лучше писать на си. ;-)

proff
()

использование _exit и _abort - попытки найти причину некорректного поведения процесса. В оригинале было так - дочерний процесс после pthread_kill_other_threads_np и установки флага close on exec для всех открытых дескрипторов файлов, кроме стандартных, должен запускать другой процесс (exec). Вот при выполнении этого exec и происходит умирание всех потоков в родителе, кроме main (работает!) и manager (defunct).

Прикол, в том, что этот код нормально работал 4 месяца, а тут - такая фигня.

anonymous
()

Пардон! Все пофиксил! Проблема была в CORBA которая использовала какие то свои pthread. Поправил Makefile и все зафунциклировало!

anonymous
()

Пардон! Все пофиксил! Проблема была в CORBA которая использовала какие то свои pthread. Поправил Makefile и все зафунциклировало!

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

Пардон! Все пофиксил! Проблема была в CORBA которая использовала какие то свои pthread. Поправил Makefile и все зафунциклировало!

anonymous
()

Пардон! Все пофиксил! Проблема была в CORBA которая использовала какие то свои pthread. Поправил Makefile и все зафунциклировало!

Чегото не появляеттся это сообщение. Попадает в удаленные.

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