2012-06-03 3 views
2

У меня есть C++ pthread Thread, вызывающий скрипты оболочки с помощью Popen.Сбой pthread_join заставляет дочерний процесс быть зомби?

То, что наблюдается в одном случае, заключается в том, что неудача pthread_join улавливается (т.е. pthread_join! = 0), а дочерний процесс остается зомби (в соответствии с выходом ps).

Это также приводит к зависанию основной программы.

Прямо сейчас, я не знаю, почему pthread_join потерпит неудачу, потому что это никогда не было в других сценариях.

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

Заранее спасибо ..

+0

Да, я имел это в виду. но попробовать, поскольку pthread_join инкапсулируется как общая библиотека. я отложил его для следующего теста. – Vivek

ответ

1

После вызова popen, там должен быть соответствующий вызов pclose , в противном случае дочерний процесс, порожденный вызовом popen, останется в состоянии зомби. Что могло бы произойти, так это то, что поток столкнулся с необработанным исключением, вызвавшим отказ pclose, что привело к появлению зомби и «неудачному» результату pthread_join.

Одно из решений - убедиться, что ваш код правильно обрабатывает все возможные исключения.

Другим решением было бы реализовать что-то похожее на popen(), но не требует pclose(), чтобы пожинать зомби. Это можно сделать, используя двойную вилку . Вы вызываете fork(), а затем вызывайте его еще до звонка exec(). Родительский процесс позволяет промежуточному дочернему процессу выйти и быть полученным с помощью wait4(). Процесс внука теперь может выйти, не покидая зомби, так как он будет получен в результате процесса init. Чтобы создать канал связи между внуком и родителем, используйте pipe() как popen(), или socketpair(), если вам нужна двунаправленная связь. Используйте dup2() в процессе внука, чтобы ваш выбор stdin, stdout и stderr был перенаправлен через трубу или розетку перед вызовом exec().

+0

hmm, что кажется, имеет смысл. потому что это сбой соединения происходит только тогда, когда основной сокет вызывает исключение. но try-catch улавливает сбой соединения. Я проверю, является ли это pclose case и обновляет условие. – Vivek

+0

У меня есть одно сомнение. Если в моем основном процессе есть обработчик сигналов для SIGCHLD и выполняется ожидание, не удастся ли удалить зомби, даже если соединение завершится неудачей? – Vivek

+0

Я принимаю ваш ответ, так как это помогло мне решить проблему. Предыдущий поток, обработчик которого был обработан после его присоединения, был оставлен в списке, который был пройден снова для соединения при завершении текущего потока. Соединение снова вызывает сбой, и, следовательно, эта нить никогда не соединяется, оставляя процесс зомби и процесс зависания .. спасибо :) – Vivek

Смежные вопросы