C: Exec/fork> Неисправные процессы

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

Моя первая проблема заключается в том, что я запускаю процесс появления в фоновом режиме с помощью

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

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

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

Ответ 1

Сначала ваш второй вопрос!

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

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

signal(SIGCHLD, SIG_IGN);

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

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

Ответ 2

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

Когда процесс умирает (вызывая _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