Ответ 1
Ничего не эквивалентно wait()
. Обычной практикой является опрос с использованием kill(pid, 0)
и поиск возвращаемого значения -1 и errno
в ESRCH
, чтобы указать, что процесс ушел.
Для дочерних процессов функции wait()
и waitpid()
могут использоваться для приостановки выполнения текущего процесса до выхода дочернего элемента. Но эта функция не может использоваться для не-дочерних процессов.
Есть ли еще одна функция, которая может ждать выхода из любого процесса?
Ничего не эквивалентно wait()
. Обычной практикой является опрос с использованием kill(pid, 0)
и поиск возвращаемого значения -1 и errno
в ESRCH
, чтобы указать, что процесс ушел.
В BSD и OS X вы можете использовать kqueue с EVFILT_PROC + NOTE_EXIT, чтобы сделать именно это. Не требуется опрос. К сожалению, нет эквивалента Linux.
До сих пор я нашел три способа сделать это в Linux:
kill
, либо проверяя существование /proc/$pid
, как и в большинстве других ответов.ptrace
для присоединения к процессу, подобному отладчику, чтобы вы получили уведомление, когда он выходит, как в a3nm answernetlink
для прослушивания сообщений PROC_EVENT_EXIT
- таким образом ядро сообщает вашей программе каждый раз, когда процесс завершается, и вы просто ждете правильного идентификатора процесса. Я видел только описанное в одном месте в Интернете.Бесстыдный плагин: я работаю над программа (с открытым исходным кодом, конечно, GPLv2), которая делает любой из трех.
Вы также можете создать сокет или FIFO и прочитать их. FIFO особенно прост: подключите стандартный вывод вашего ребенка к FIFO и прочитайте. Чтение блокируется до тех пор, пока ребенок не выйдет (по какой-либо причине) или пока он не выдает некоторые данные. Таким образом, вам понадобится небольшой цикл для удаления ненужных текстовых данных.
Если у вас есть доступ к источнику ребенка, откройте FIFO для записи, когда он начнется, а затем просто забудьте об этом. ОС очистит дескриптор открытого файла, когда ребенок завершит работу, и ваш ожидающий "родительский" процесс проснется.
Теперь это может быть процесс, который вы не начали или не создали. В этом случае вы можете заменить исполняемый файл двоичным кодом script, который запускает реальный двоичный файл, но также добавляет мониторинг, как описано выше.
Вы можете прикрепить к процессу ptrace(2)
. Из оболочки кажется, что strace -p PID >/dev/null 2>&1
работает. Это позволит избежать оживленного ожидания, хотя это замедлит отслеживаемый процесс и не будет работать на всех процессах (только ваши, что немного лучше, чем только дочерние процессы).
Нет. Я знаю. Помимо решения хаоса, вы можете использовать семафоры, если вы можете изменить программу, которую вы хотите подождать.
Библиотечные функции sem_open(3)
, sem_init(3),
sem_wait(3),
...
sem_wait(3)
выполняет ожидание, поэтому вам не нужно делать ожидание, как в решении хаоса. Конечно, использование семафоров делает ваши программы более сложными, и это может не стоить проблем.
Может быть, можно будет ждать, пока /proc/ [pid] или/proc/[pid]/[something] исчезнет?
Есть функции poll() и другие функции ожидания событий файла, возможно, это может помочь?
Я нашел следующий способ ожидания в Linux для завершения данного процесса без опроса:
Сначала используйте readlink ("/proc/'pid'/exe",...), чтобы получить путь к исполняемому файлу. Пока процесс существует, этот файл остается открытым.
Затем используйте inotify с IN_CLOSE_NOWRITE, чтобы заблокировать, пока файл не будет закрыт. Конечно, он может быть закрыт по другим причинам (например, другой процесс с такими же исполняемыми выходами), поэтому вы должны фильтровать эти события другими способами.
Чтобы быть на 100% защищенным от возможных проблем повторного использования pid, вы можете оставить /proc/'pid открытым. Даже если новый процесс создается с тем же pid, старый дескриптор открытого файла /proc/'pid' не будет соответствовать новому процессу, поэтому вы можете проверить, существует ли там файл exe с помощью openat(). Если он больше не существует, процесс должен быть завершен