
Если это процесс, которым вы ожидаете «владеть» (например, вы используете его для проверки pid для процесса, которым вы управляете), вы можете просто отправить ему sig 0.
>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
from (irb):5:in `kill'
from (irb):5
>>
блин, опереди меня. Я увидел, что «отправлены новые ответы», и у меня упало сердце :(
Но что такое сигнал 0? Нет?
На моей странице руководства: значение 0, однако, вызовет проверку ошибок (без отправки сигнала). Это можно использовать для проверки действительности pid.
Черт возьми, смотрел страницу руководства по сигналам и т. д. Не подумал заглянуть на страницу руководства kill. :) Спасибо, Дастин.
к сожалению, это также возвращает 1, если процесс находится в состоянии «зомби», поэтому не сообщает вам, мертв ли процесс, а только о том, существует ли процесс с этим PID где-то в системе (например, если у вас есть открытый поток для процесс, это вернет 1, даже если процесс завершился). Также обратите внимание, что PID могут повторно использоваться ОС ...
Вы можете попробовать использовать
Process::kill 0, pid
где pid - это номер pid, если pid запущен, он должен вернуть 1.
@John T, @Dustin: На самом деле, ребята, я просмотрел rdocs процесса, и похоже,
Process.getpgid( pid )
менее жестокий способ применения той же техники.
Я обнаружил, что это может возвращать ложные срабатывания (он сообщает о работе, хотя на самом деле это не так) в последней версии Ubuntu. Не знаю почему, но в этой теме мне показалось, что работает только решение от @balu.
Я предполагаю, что это не кроссплатформенное решение. (Это не работает в Windows, правда?)
Я думаю, здесь подразумевается, что kill 0 «жестокий» - это ошибка. В документации говорится: «Если sig равен 0, то сигнал не отправляется, но проверка ошибок по-прежнему выполняется; это можно использовать для проверки наличия идентификатора процесса или идентификатора группы процессов».
Получение NotImplementedError (getpgid() function is unimplemented on this machine) на машине Windows. любая помощь?
@ManivannanJeganathan Это не работает в Windows. Вместо этого используйте другое решение. (Может быть, Вот этот).
Разница между подходами Process.getpgid и Process::kill, похоже, заключается в том, что происходит, когда pid существует, но принадлежит другому пользователю. Process.getpgid вернет ответ, Process::kill выдаст исключение (Errno::EPERM).
Исходя из этого, я рекомендую Process.getpgid, хотя бы по той причине, что он избавляет вас от необходимости перехватывать два разных исключения.
Вот код, который я использую:
begin
Process.getpgid( pid )
true
rescue Errno::ESRCH
false
end
Как убить процесс, принадлежащий другому пользователю?
лайнер: (Process.getpgid(pid) rescue nil).present?
Для дочерних процессов другие решения, такие как отправка сигнала, не будут вести себя должным образом: они укажут, что процесс все еще запущен, когда он фактически завершился.
Вы можете использовать Process.waitpid, если хотите проверить процесс, который вы создали сами. Вызов не будет заблокирован, если вы используете флаг Process::WNOHANG, и nil будет возвращен, пока дочерний процесс не завершился.
Пример:
pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid
Если pid не принадлежит дочернему процессу, будет сгенерировано исключение (Errno::ECHILD: No child processes).
То же самое относится к Process.waitpid2.
Я обнаружил, что это более надежно, чем вышеупомянутые решения. Спасибо!
Спасибо, это самый надежный ответ для порожденных процессов. Для не порожденных нами процессов подойдут и другие решения.
Кажется, это единственный ответ, который работает с окнами, по крайней мере, для меня: D
Подход, использующий только *nix, заключался бы в том, чтобы выполнить оболочку ps и проверить, существует ли в возвращаемой строке разделитель \n (новая строка).
Пример вывода IRB
1.9.3p448 :067 > `ps -p 56718`
" PID TTY TIME CMD\n56718 ttys007 0:03.38 zeus slave: default_bundle \n"
Упаковано как метод
def process?(pid)
!!`ps -p #{pid.to_i}`["\n"]
end
В Linux вы можете получить множество атрибутов запущенной программы, используя файловую систему proc:
File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
Я имел дело с этой проблемой раньше, а вчера я скомпилировал ее в гем "process_exists".
Он отправляет нулевой сигнал (0) процессу с заданным pid, чтобы проверить, существует ли он. Он работает, даже если у текущего пользователя нет разрешений на отправку сигнала принимающему процессу.
Использование:
require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)
Вот как я это делал:
def alive?(pid)
!!Process.kill(0, pid) rescue false
end
Обычно вы никогда не захотите использовать rescue таким образом, но здесь это кажется оправданным.
Интересный подход! Я исследую это.