Подтвердить что ты не робот

Как дождаться выхода из не-детских процессов

Для дочерних процессов функции wait() и waitpid() могут использоваться для приостановки выполнения текущего процесса до выхода дочернего элемента. Но эта функция не может использоваться для не-дочерних процессов.

Есть ли еще одна функция, которая может ждать выхода из любого процесса?

4b9b3361

Ответ 1

Ничего не эквивалентно wait(). Обычной практикой является опрос с использованием kill(pid, 0) и поиск возвращаемого значения -1 и errno в ESRCH, чтобы указать, что процесс ушел.

Ответ 2

В BSD и OS X вы можете использовать kqueue с EVFILT_PROC + NOTE_EXIT, чтобы сделать именно это. Не требуется опрос. К сожалению, нет эквивалента Linux.

Ответ 3

До сих пор я нашел три способа сделать это в Linux:

  • Опрос: вы проверяете существование процесса так часто, либо используя kill, либо проверяя существование /proc/$pid, как и в большинстве других ответов.
  • Используйте системный вызов ptrace для присоединения к процессу, подобному отладчику, чтобы вы получили уведомление, когда он выходит, как в a3nm answer
  • Используйте интерфейс netlink для прослушивания сообщений PROC_EVENT_EXIT - таким образом ядро ​​сообщает вашей программе каждый раз, когда процесс завершается, и вы просто ждете правильного идентификатора процесса. Я видел только описанное в одном месте в Интернете.

Бесстыдный плагин: я работаю над программа (с открытым исходным кодом, конечно, GPLv2), которая делает любой из трех.

Ответ 4

Вы также можете создать сокет или FIFO и прочитать их. FIFO особенно прост: подключите стандартный вывод вашего ребенка к FIFO и прочитайте. Чтение блокируется до тех пор, пока ребенок не выйдет (по какой-либо причине) или пока он не выдает некоторые данные. Таким образом, вам понадобится небольшой цикл для удаления ненужных текстовых данных.

Если у вас есть доступ к источнику ребенка, откройте FIFO для записи, когда он начнется, а затем просто забудьте об этом. ОС очистит дескриптор открытого файла, когда ребенок завершит работу, и ваш ожидающий "родительский" процесс проснется.

Теперь это может быть процесс, который вы не начали или не создали. В этом случае вы можете заменить исполняемый файл двоичным кодом script, который запускает реальный двоичный файл, но также добавляет мониторинг, как описано выше.

Ответ 5

Вы можете прикрепить к процессу ptrace(2). Из оболочки кажется, что strace -p PID >/dev/null 2>&1 работает. Это позволит избежать оживленного ожидания, хотя это замедлит отслеживаемый процесс и не будет работать на всех процессах (только ваши, что немного лучше, чем только дочерние процессы).

Ответ 6

Нет. Я знаю. Помимо решения хаоса, вы можете использовать семафоры, если вы можете изменить программу, которую вы хотите подождать.

Библиотечные функции sem_open(3), sem_init(3), sem_wait(3),...

sem_wait(3) выполняет ожидание, поэтому вам не нужно делать ожидание, как в решении хаоса. Конечно, использование семафоров делает ваши программы более сложными, и это может не стоить проблем.

Ответ 7

Может быть, можно будет ждать, пока /proc/ [pid] или/proc/[pid]/[something] исчезнет?

Есть функции poll() и другие функции ожидания событий файла, возможно, это может помочь?

Ответ 8

Я нашел следующий способ ожидания в Linux для завершения данного процесса без опроса:

Сначала используйте readlink ("/proc/'pid'/exe",...), чтобы получить путь к исполняемому файлу. Пока процесс существует, этот файл остается открытым.

Затем используйте inotify с IN_CLOSE_NOWRITE, чтобы заблокировать, пока файл не будет закрыт. Конечно, он может быть закрыт по другим причинам (например, другой процесс с такими же исполняемыми выходами), поэтому вы должны фильтровать эти события другими способами.

Чтобы быть на 100% защищенным от возможных проблем повторного использования pid, вы можете оставить /proc/'pid открытым. Даже если новый процесс создается с тем же pid, старый дескриптор открытого файла /proc/'pid' не будет соответствовать новому процессу, поэтому вы можете проверить, существует ли там файл exe с помощью openat(). Если он больше не существует, процесс должен быть завершен