2011-02-03 2 views
0

내가 여기 Process.waitRuby에서 트랩 처리기와의 동시성 제한이 있습니까?

require 'pp' 

children = [] 
trap("CLD") do 
    cpid = Process.wait 
    puts "CLD from pid #{cpid} at #{Time.now}" 
    6.times {|i| puts " ... Waiting[#{i}] in CLD trap for pid #{cpid}"; sleep 0.5} 
    puts "OK, finished slow trap at #{Time.now} for pid #{cpid}" 
    children.delete cpid 
end 

4.times {|i| 
    if child_pid = fork # parent 
     puts "In parent, child_pid[#{i}] = #{child_pid}" 
     children.push child_pid 
    else 
     puts "In child[#{i}], PID=#{$$}" 
     sleep 0.2 
     puts "In child[#{i}], PID=#{$$} ... exiting" 
     exit! 
    end 
    } 

while true 
    sleep 2 
    exit if children.length == 0 
    puts "[#{Time.now}] ... Parent still waiting for \n" 
    pp children 
    sleep 8 
end 

를 사용하여, 따라서 종료 상태를 가지고 있지 않은 소멸 (좀비) 프로세스를 떠나 손실 수집됩니다 다음 코드와 CLD 트랩 (하나 이상)를 실행하는 샘플입니다 실행 출력 :

[[email protected] pe2]# ruby multitrap.rb 
In parent, child_pid[0] = 9285 
In child[0], PID=9285 
In parent, child_pid[1] = 9289 
In child[1], PID=9289 
In parent, child_pid[2] = 9293 
In child[2], PID=9293 
In parent, child_pid[3] = 9297 
In child[3], PID=9297 
In child[0], PID=9285 ... exiting 
In child[3], PID=9297 ... exiting 
In child[1], PID=9289 ... exiting 
In child[2], PID=9293 ... exiting 
CLD from pid 9285 at 2011-02-03 13:31:20 -0800 
    ... Waiting[0] in CLD trap for pid 9285 
CLD from pid 9289 at 2011-02-03 13:31:20 -0800 
    ... Waiting[0] in CLD trap for pid 9289 
CLD from pid 9293 at 2011-02-03 13:31:20 -0800 
    ... Waiting[0] in CLD trap for pid 9293 
    ... Waiting[1] in CLD trap for pid 9293 
    ... Waiting[2] in CLD trap for pid 9293 
    ... Waiting[3] in CLD trap for pid 9293 
    ... Waiting[4] in CLD trap for pid 9293 
    ... Waiting[5] in CLD trap for pid 9293 
OK, finished slow trap at 2011-02-03 13:31:23 -0800 for pid 9293 
    ... Waiting[1] in CLD trap for pid 9289 
    ... Waiting[2] in CLD trap for pid 9289 
    ... Waiting[3] in CLD trap for pid 9289 
    ... Waiting[4] in CLD trap for pid 9289 
    ... Waiting[5] in CLD trap for pid 9289 
OK, finished slow trap at 2011-02-03 13:31:25 -0800 for pid 9289 
    ... Waiting[1] in CLD trap for pid 9285 
    ... Waiting[2] in CLD trap for pid 9285 
    ... Waiting[3] in CLD trap for pid 9285 
    ... Waiting[4] in CLD trap for pid 9285 
    ... Waiting[5] in CLD trap for pid 9285 
OK, finished slow trap at 2011-02-03 13:31:28 -0800 for pid 9285 
[2011-02-03 13:31:28 -0800] ... Parent still waiting for 
[9297] 
[2011-02-03 13:31:38 -0800] ... Parent still waiting for 
[9297] 
[2011-02-03 13:31:48 -0800] ... Parent still waiting for 
[9297] 
[2011-02-03 13:31:58 -0800] ... Parent still waiting for 
[9297] 

... 등등 ...

그런 다음 '추신 AXF는'

9283 pts/2 Sl+ 0:00 | |  \_ ruby multitrap.rb 
9297 pts/2 Z+  0:00 | |   \_ [ruby] <defunct> 
를 보여줍니다 내 실험
3 children .... sometimes gets a zombie 
    4 children .... more often gets a zombie 
    5 children .... always gets a zombie, sometimes more than one 

여기에 제한은 무엇입니까

에서 17,451,515,

?

CLD 트랩 처리기를 설정하여 필요한만큼 동시에 여러 개의 자식 종료를 처리 할 수 ​​있습니까?

루비 버전은 루비 1.9.1p243 (2009-07-16 개정 24175) [x86_64에-리눅스] 내가 파이썬에서 비슷한 문제를 해결 한

답변

1

감사합니다 ...입니다. 루비가 시그널 처리를 구현하는 방법에 따라, 트랩 처리기의 이전 호출이 실행 중일 때 자식이 종료되면 트랩 처리기가 다시 호출되지 않을 수 있습니다.

따라서 안전한 디자인은 루프를 사용하고 단일 트랩 처리기 실행에서 가능한 모든 자식을 확보하는 것입니다. 이렇게하기 위해서는 이미 자녀 목록이 있다는 가정이 있습니다.

- 트랩 다음 목록

0

개성있는 루비에서 항목을 제거 수확 아이들의 각 child_pid RC = waitpid를위한 (CHLD) (PID, WNOHANG) 경우는 힌트 :

  1. 4.times {|i|입니다 대개 4.times do |i| 인 경우 여러 줄로 표시됩니다.
  2. pp children은 두 가지가 별도의 줄에 있어야한다는 의미가 아니라면 "waiting for #{children.inspect}"으로 바꿀 수 있습니다.
+0

필자는 필자가 일치하는 항목을 확인하고 앞뒤로 건너 뛰는 편집기를 사용할 수 있기 때문에 언제든지 중괄호를 사용하는 경향이 있습니다. 나는 두 가지 스타일 사이에 약간의 기능적 차이가 있다고 생각하지만, 그것이 무엇인지를 기억하지 못한다. 또한 중괄호가 시각적으로 더 매력적입니다. 자기 자신에게. –