Выполнение новой задачи на основе sigchld () из предыдущей задачи - PullRequest
1 голос
/ 13 ноября 2011

В настоящее время я работаю над созданием небольшой оболочки в C ++.

Пользователь может вводить задание по приглашению, например exe1 && exe2 &.Подобно оболочке BASH, я выполню exe2, только если exe1 успешно завершится.Кроме того, вся работа должна выполняться в фоновом режиме (как указано в конце оператора &).

Сейчас у меня есть jobManager, который обрабатывает выполнение заданий, и структура jobкоторый содержит исполняемый файл задания и его отдельные аргументы / условия.Задание начинается с вызова fork() и последующего вызова execvp() с надлежащими аргументами.Когда работа заканчивается, у меня есть обработчик сигнала для SIGCHLD, в котором я выполняю wait(), чтобы определить, какой процесс только что закончился.Когда exe1 заканчивается, я наблюдаю код его выхода и решаю, стоит ли мне начинать запуск exe2.

Меня беспокоит, как мне запустить exe2.Я обеспокоен тем, что, если я использую свою функцию запуска jobManager из контекста моего обработчика SIGCHLD, я могу получить слишком много функций обработчика SIGCHLD, висящих в стеке (например, если было 10 условных выполнений).Кроме того, не очень хорошая идея начинать следующее выполнение из обработчика сигнала, даже если это происходит косвенно.(Я пытался сделать что-то подобное 1,5 года назад, когда я только учился обрабатывать сигналы - похоже, я вспомнил, что мне это не удалось).

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

Любая обратная связь оценивается.

Ответы [ 2 ]

1 голос
/ 13 ноября 2011

Я вижу два пути:
1) Замените вас sighandler на петлю, которая называется "sigwait" (см. Man 3 sigwait)
затем в цикле

2) перед началом создания pipe и в mainloop вашей программы используйте "select" на дескрипторе pipe, чтобы ждать События. В обработчике сигнала пишите в трубу, а в ситуации с ручкой mainloop.

0 голосов
/ 13 ноября 2011

Хммм, это хорошо.

Как насчет разветвления дважды, один раз за процесс? Первый работает, а второй останавливается. В родительском обработчике SIGCHLD отправьте SIGCONT второму дочернему элементу, если необходимо, который затем отключается и запускает задание. Естественно, вы SIGKILL второй, если первый не должен работать, что должно быть безопасно, потому что вы ничего не настроили.

Как это звучит? У вас будет процесс, сидящий без дела, но он не должен быть очень долгим.

...