2011-01-17 3 views
0

Если я запустить приложение следующим образомВ Ruby говорится, что системный процесс все еще жив?

cmd = "some_app &" 
`#{cmd}` 

Как я могу узнать, если процесс все еще жив? Я знаю, что есть различные способы получения pid запущенного приложения, и я мог бы проверить, был ли он по-прежнему доступен через ps -ef. Однако это только скажет мне, был ли процесс, который существовал с одним и тем же pid, когда приложение могло быть убито ранее. Та же проблема существует с подходом ps -ef | grep some_app.

У кого-нибудь есть идеи чистого пути для достижения этого?

ответ

1

$alive = true 
Thread.new do 
    `some_app` 
    $alive = false 
end 

if $alive 
    ... 
4

Это не может быть сделано в общем случае; Возможности Unix для управления процессами ограничены и недостаточно хорошо интегрированы с остальной частью API ядра (например, нет способа получить дескриптор файла для процесса, который может быть передан в select или тому подобное).

Чтобы заблокировать или опросить дочерний процесс, вы можете использовать wait family of functions. Вы можете установить обработчик для SIGCHLD и получать асинхронное уведомление при выходе из него. И, в сотрудничестве с дочерним процессом, вы можете использовать трубку или сокет, чтобы получить более подробную информацию о том, что происходит. Тем не менее, при активном недостает сотрудничества с ребенком, вы попадаете (например, ребенок, который сам вилки, выходы у ребенка, а звонки setsid в внуке сбежали с отслеживания в исходном родителе).

Это в значительной степени ваши варианты, если только вы не готовы углубиться в землю системного кода (например, некоторые люди сделали умные вещи с помощью ptrace, что обычно для отладчиков, для решения разновидностей проблем вы смотрите, но я бы не пробовал, кроме как в крайнем случае).

+0

Hmmmm вы имеете получил меня nking, предположительно, каждый процесс имеет родительский процесс текущего работающего рубинового интерпретатора где-то в дереве процессов. Разве это не просто работа над деревом, начинающимся с мастер-процесса рубинового переводчика? (Я предполагаю, что это то, о чем вы говорили с ptrace). – Jamie

+0

Да, за исключением того, что процесс не может «ждать» ничего, кроме его прямых детей, нет никакого переносного способа для обработки дерева процессов, и если промежуточный ребенок выходит из него, все, что ниже этой точки, получает «репарацию» для обработки 1 («init»)), поэтому, даже если вы * можете * ходить по дереву процессов, вы не обязательно сможете найти всех своих потомков. – zwol

2

исследуемыми это на предшествующем уровне проекта ...

Видимо, общая практика использования Process.kill(0, pid) зондировать ФИД, чтобы увидеть, может ли быть послан сигнал. Этот метод вернет true только в том случае, если процесс существует как , так и, вызывающий абонент имеет разрешение на его передачу. Возвращаемое значение false может означать, что процесс не существует или у пользователя нет соответствующего разрешения. или pid - неправильный тип (то есть строка) или ...

Вы можете поймать конкретное исключение что указывает на несуществования, Errno::ESRCH, «нет такого процесса», различая, что из-за отсутствия разрешения и т.д.

def process_exists?(pid) begin Process.kill(0, pid) rescue Errno::ESRCH # "No such process" return false rescue Errno::EPERM # "Operation not permitted" # at least the process exists return true else return true end end

Очевидно не пуленепробиваемые, но это начало ...

+0

Да, так вы все хорошо. – tchrist

+0

Это на самом деле не работает (если я не пропущу что-то). Как я уже сказал в вопросе, если процесс умирает, а новый процесс получает тот же pid, он будет показывать ложный результат. – Jamie

+0

Это не удовлетворяет «как мне сказать, если процесс все еще жив», но он удовлетворяет еще одному важному вопросу: «Как я могу узнать, существует ли ПИД-код?» (Что было предложено в другом месте: https://stackoverflow.com/questions/325082/how-can-i-check-from-ruby-whether-a-process-with-a-certain-pid-is-running.) – Ray

Смежные вопросы