Я пишу Perl-скрипт, который анализирует лог-файлы для сбора PID, а затем проверяет, работает ли этот PID. Я пытаюсь придумать лучший способ сделать эту проверку. Очевидно, я мог бы сделать что-то вроде:
system("ps $pid > /dev/null") && print "Not running\n";
Однако я бы предпочел избегать системного вызова, если это возможно. Поэтому я подумал, что могу использовать /proc
файловую систему (переносимость не имеет значения, она всегда будет работать в системе Linux). Например:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Это безопасно? Могу ли я всегда предполагать, что если нет /proc/$pid/
каталога, связанный PID не работает? Я ожидаю, что так как AFAIK все равно ps
получает информацию, /proc
но так как это для производственного кода, я хочу быть уверен.
Итак, могут ли быть случаи, когда запущенный процесс не имеет /proc/PID
каталога или /proc/PID
каталог существует, а процесс не запущен? Есть ли какая-либо причина, чтобы предпочесть разбор ps
проверке существования каталога?
источник
kill
функция perl, использующая сигнал 0, который не убивает, а говорит, что если вы можете это сделать (то есть вам нужно разрешение для сигнализации этого процесса).kill -0
он лучший), он только сообщает вам , есть ли запущенный процесс с данным PID . Он не сообщает вам, будет ли процесс по-прежнему выполняться через одну миллисекунду, и не сообщает вам, является ли этот процесс тем, который вас интересует, или не связанным процессом, который получил тот же PID после того, как интересный процесс умер , Почти всегда ошибочно проверять, работает ли данный PID : очень мало обстоятельств, когда это не подвержено условиям гонки.Ответы:
kill(0,$pid)
Можно использовать функцию perl .Если код возврата равен 1, тогда PID существует, и вы можете отправить ему сигнал.
Если код возврата равен 0, то вам нужно проверить $ !. Это может быть EPERM (отказано в разрешении), что означает, что процесс существует, или ESRCH, в этом случае процесс не существует.
Если ваш проверочный код работает как,
root
то вы можете упростить это до простой проверки кода возврата kill; 0 => ошибка, 1 => хорошоНапример:
Это можно сделать простой функцией
источник
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
или похоже. Мне нравится вашеErrno
решение, хотя, спасибо. Хотя я, вероятно, пойду с этим, подожду немного, если кто-нибудь сможет ответить на основной вопрос Linux./proc
смонтирован, то будет присутствовать каждый PID, видимый в пространстве имен, поэтому ваш-d /proc/$pid
тест будет работать ... но он предполагает выход в файловую систему, а не с использованием системных системных вызовов.system
вызов», то есть вызов самойsystem
функции, а не «системный вызов» . Последнее вы не можете избежать, но первое вы, конечно, можете. Имеет смысл сейчас!/proc/PID
kill 0
/proc
/proc
ps
,top
и ,lsof
вероятно , не будет работать - и поэтому это может не быть проблемой для производственной системы. Но (теоретически) возможно, что он никогда не был смонтирован (хотя это может помешать системе перейти в нормальное состояние), вполне возможно, что он будет размонтирован (я проверял 1)), и я считаю, что нет никаких гарантий, что он будет существовать (то есть, это не требуется POSIX). И, если система полностью не подключена,kill
будет работать./proc
требует чтения корневого каталога , чтобы найти в/proc
файловой системе. Это верно для любой попытки получить доступ к любой файл, полное составное имя, в том числе вещей , в/bin
,/etc
и/dev
. Это происходит так часто, что корневой каталог надежно кэшируется в памяти в течение всего времени жизни (времени безотказной работы) системы, поэтому этот шаг можно выполнить без дискового ввода-вывода. И, когда у вас есть инод/proc
, все остальное, что происходит, находится в памяти./proc
? Сstat
,open
,readdir
и т.д., которые являются родные системных вызовов каждый бит столько , сколькоkill
.Вопрос говорит о запущенном процессе. Это скользкая фраза. Если вы действительно хотите проверить, запущен ли процесс (т. Е. В очереди выполнения; может быть, текущий процесс на каком-либо процессоре; не спит, не ждет или не остановлен), вам может потребоваться выполнить a и прочитать вывод или посмотреть на , Но я не вижу в вашем вопросе или комментариях намека на то, что вы обеспокоены этим.
ps PID
/proc/PID/stat
Слон в комнате, однако, состоит в том, что процесс зомби 2 может быть трудно отличить от процесса, который жив и здоров.
kill 0
работает на зомби и существует. Вы можете идентифицировать зомби с помощью методов, перечисленных в предыдущем параграфе (делать и читать вывод или смотреть на ). Мой очень быстро и случайным (то есть, не очень тщательно) тестирование предполагает , что вы можете сделать это делать или на , или - они будут терпеть неудачу на зомби. (Тем не менее, они также потерпят неудачу в процессах, которыми вы не владеете.)/proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1, если опция
-f
( f orce) не работает, попробуйте-l
( l azy).2 т.е. процесс, который завершился / умер / завершился, но родитель которого еще не сделал a
wait
.источник
kill(2)
справочная страница прямо указывает на поведение, на которое вы указали, ноperlfunc
справочная страница делает. Я отправлю электронное письмо Майклу Керриску, чтобы узнать, что он скажет о справочной странице системы.kill(2)
отправил отчет об ошибке, чтобы уточнить страницу руководства, касающуюся разрешений на «отправку» сигнала 0.kill(2)
справочную страницу (я пока не вижу его в сети): «Если sig равен 0, то сигнал не отправляется, но проверки существования и разрешений по-прежнему выполняются; это можно использовать для проверки существования идентификатор процесса или идентификатор группы процессов, о которых разрешено сигнализировать вызывающей стороне. "