C: Exec / fork> несуществующие процессы - PullRequest
13 голосов
/ 16 июля 2011

Я хочу создать множество дочерних процессов, используя процедуру fork> exec.Многие процессы заканчиваются очень быстро (менее чем за две минуты, некоторые даже раньше).

Моя первая проблема - я поставил процесс появления в фоновом режиме с помощью

./spawnbot > logging.txt
[CTRL+Z]
bg 1
disown

Пока чтохорошо.Теперь я больше не вижу сообщений spawnbot, и они попадают прямо в logging.txt.Тем не менее, всякий раз, когда создается новый дочерний элемент, я снова вижу всю информацию об этом дочернем элементе в своей консоли ... Теперь я хотел запустить каждого дочернего элемента со своим собственным каналом - есть ли лучший способ, чтобы дочерние элементы не публиковали свои выходные сообщения поприставка?Должен ли я просто перенаправить его в / dev / null или это делается с каким-то флагом в C?

Во-вторых, все дети на самом деле не погибают.У меня много процессов в моем ps -ef.Что я могу с этим поделать?Как мне д

Ответы [ 2 ]

18 голосов
/ 16 июля 2011

Первый ваш второй вопрос!

Ваши дети остаются в режиме «зомби», потому что ядро ​​считает, что вы все еще можете получить от них возвращаемое значение ..

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

signal(SIGCHLD, SIG_IGN);

Первый вопрос зависитэто в вашей реализации ..

Но, вообще говоря, сразу после fork () вы должны использовать close(), чтобы закрыть старые файловые дескрипторы для 0 и 1, а затем использовать dup2(), чтобы установить их в свойразыскиваемые ценности .. Сейчас нет времени для примера, но надеюсь, что это подтолкнет вас в правильном направлении ..

14 голосов
/ 16 июля 2011

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

Когда процесс умирает (вызывая _exit или убиваетсясигнал), его должен пожинать родитель.Каждый ресурс, используемый процессом, кроме записи в таблице процессов, исчезает.Родитель должен позвонить wait или waitpid.Как только родитель получит уведомление о смерти дочернего процесса и получит возможность прочитать статус выхода ребенка, запись о ребенке также исчезнет из таблицы процессов:

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

signal(SIGCHLD, SIG_IGN)

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

struct sigaction sa;
sa.sa_handler = &my_sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &sa, NULL);

Что касается вывода, ваши дети будут писать в те же места, что и родитель, если вы не перенаправили их явно (с помощью close и open или dup, или ряд других возможностей).Ваши дети, вероятно, печатают диагностические сообщения к стандартной ошибке (в конце концов, для этого она и нужна).

./spawnbot >logging.txt 2>&1

Кроме того, поскольку вы, похоже, хотите отсоединить детей от терминала, вы, вероятно, захотите убедиться, что они не получат SIGHUP , если вы убьете терминал.Так что используйте nohup:

nohup ./spawnbot >logging.txt 2>&1 &
disown
...