Дождитесь завершения несвязанного процесса без условий гонки - PullRequest
0 голосов
/ 11 декабря 2018

В Windows вы не можете напрямую общаться или взаимодействовать с идентификатором процесса.Скорее, идентификатор процесса действует как «имя файла» для запущенного процесса.Если вы хотите взаимодействовать с процессом, вы «открываете» его, что дает вам маркер .Этот дескриптор на протяжении своего времени постоянно связан с процессом, так же, как дескриптор файла постоянно связан с данным файлом, даже если вы играете с узлом файловой системы, пока он открыт.Также, помимо прочего, дескриптор действует как объект синхронизации ядра, в частности, объект события.Событие становится сигнальным при выходе из процесса.Дескриптор может использоваться в вызовах ОС, таких как WaitForSingleObject, которые блокируют поток, пока не произойдет событие.Это означает две вещи:

  1. Вы можете ждать завершения процесса с потоком, который полностью заблокирован и не запланирован для выполнения, пока не произойдет событие.

  2. Когда у вас есть этот дескриптор процесса, он всегда относится к этого конкретного процесса, независимо от того, что происходит с повторным использованием PID.Вы заблокированы в этом процессе, как только успешно его открыли.

В системах UNIX лучшее, что я смог найти для ожидания несвязанного процесса для выхода, - этоЦикл опроса, который сигнализирует PID каждые n миллисекунд (где n обычно составляет 500 или 1000).Наблюдатель замечает, что процесс завершился, когда PID больше не может принимать сигнал.Это означает, что до того, как наблюдатель заметит, может пройти полный интервал, и если другой процесс запустится с тем же PID в течение этого интервала, он будет ложно продолжать наблюдение, неосознанно переключившись на просмотр нового процесса.(Возможно, что-то препятствует повторному использованию PID в течение короткого промежутка времени, чтобы смягчить именно эту проблему? Однако я не смог найти ничего подобного задокументированному.)

Даже tail --pid работает таким образом.

Есть ли способ в системах UNIX (или, возможно, в каком-то конкретном ядре UNIX-y) надежно ждать завершения процесса, без задержки опроса или риска (хотя обычно минимального) повторного использования PID?

Я немного поэкспериментировал с файловыми дескрипторами в /proc/$PID/fd в системе Linux.Я надеялся, что stdout может быть закрыт при выходе из процесса.Но, похоже, процесс наследует свой родительский поток.Таким образом, чтение из него не только мешает обычной работе программы, но и при выходе из процесса, если у родителя все еще остается то же самое открытое stdout, тогда даже если /proc/$PID/fd исчезает, дескриптор, открытый из него, продолжаетуказать на действительный объект ядра.Если я запускаю программу на одном терминале и cat /proc/$PID/fd/1, то cat крадет вывод этой программы.Но когда эта программа завершается, cat продолжает работать, теперь крадя выходные данные родительского процесса (например, оболочки).cat выходит только после полного отключения терминала.Вот вам и идея!

...