2011-08-20 3 views
1

루비에서 필자는 꼬리와 유사하게 파일의 변경 사항을 지속적으로 감시하는 시스템 ("명령")을 운영하고 있습니다. 내 프로그램이 계속 실행되고 system() 호출에서 중단되지 않도록하고 싶습니다. Ruby에서 다른 프로세스를 생성하여 둘 다 독립적으로 실행하고 결과를 터미널에 출력 한 다음 프로그램을 종료하면 생성 된 응용 프로그램이 제거됩니다.루비는 두 개의 프로세스를 실행하여 결과를 터미널에 출력하고 안전하게 종료합니다.

+0

프로그램이 종료 될 때 모든 하위 프로세스를 종료 하시겠습니까? 아니면 종료하기 전에 아이들이 스스로 끝내기를 기다리시겠습니까? –

+0

은 프로그램이 종료 될 때 모든 하위 프로세스를 종료합니다. 두 프로세스 모두 파일의 변경 사항을 감시하므로 실제로 완료되지 않습니다. – jaysonp

답변

2

그냥 spawnwaitall을 결합 :

spawn 'sleep 6' 
spawn 'sleep 8' 
Process.waitall 
2

당신은 프로세스가 완료 될 때까지 그 기다립니다 system를 사용하지 않습니다. spawn 대신에 wait을 사용하면 좀비를 피할 수 있습니다. 그런 다음 종료 할 때 생성 된 프로세스에 SIGTERM을 보냅니다. fork을 사용하여 하위 프로세스를 시작할 수도 있지만 외부 프로그램을 사용하는 경우 spawn이 더 쉽습니다.

모든 프로세스 ID를 추적하는 대신 프로세스 그룹을 사용할 수도 있습니다. 그러면 단일 Process.kill('TERM', -process_group_id) 호출이 처리 할 수 ​​있습니다. 하위 프로세스는 동일한 프로세스 그룹에 있어야하지만 필요하면 Process.setpgid이 있어야합니다.

여기에 fork을 사용하는 예가 있습니다. 모든 패키지를 하나의 패키지로 쉽게 포장 할 수 있습니다.

def launch(id, sleep_for) 
    pid = Process.fork do 
     while(true) 
      puts "#{id}, pgid = #{Process.getpgid(Process.pid())}, pid = #{Process.pid()}" 
      sleep(sleep_for) 
     end 
    end 
    # No zombie processes please. 
    Process.wait(pid, Process::WNOHANG) 
    pid 
end 

# These just forward the signals to the whole process group and 
# then immediately exit. 
pgid = Process.getpgid(Process.pid()) 
Signal.trap('TERM') { Process.kill('TERM', -pgid); exit } 
Signal.trap('INT') { Process.kill('INT', -pgid); exit } 

launch('a', 5) 
launch('b', 3) 
while(true) 
    puts "p, pgid = #{Process.getpgid(Process.pid())}, pid = #{Process.pid()}" 
    sleep 2 
end 

당신은 하나 개의 터미널에서 다음 것은 (쉘의 kill 명령을 사용하여) 서로를 죽일 아이들도 사망하는 것을 볼 수 있음을 실행하는 경우. "이 신호를 전체 프로세스 그룹으로 전달"Signal.trap 항목을 제거하면 간단한 SIGTERM은 자식을 계속 실행합니다.

이 모든 것은 사용자가 Unixy 시스템 (예 : Linux 또는 OSX), YMMV 다른 곳에서 작업하고 있다고 가정합니다.

0

스폰을 사용하는 것에 대해 한 번 더 투표하십시오. 우리는 생산에서 많이 사용하고 매우 안정적입니다.

관련 문제