2012-08-07 3 views
1

일부 스레드를 보유하고있는 클래스를 생성하고, 마지막으로 콜백 메소드를 호출하는 것이 현재의 목표입니다.이 도로에서는 특별한 것이 없습니다.루비 스레드 콜백 이상한 동작

실험 클래스는 주어진 IP의 특정 포트에서 몇 가지 연결 검사를 수행하여 상태 정보를 제공합니다.

그래서 내 시도 :

check = ConnectionChecker.new do | threads | 
    # i am done callback 
end 

check.check_connectivity(ip0, port0, timeout0, identifier0) 
check.check_connectivity(ip1, port1, timeout1, identifier1) 
check.check_connectivity(ip2, port2, timeout2, identifier2) 

sleep while not check.is_done 

어쩌면 가장 좋은 방법은, 그러나 일반적으로 내 경우에 적합합니다.

그래서 무슨 일이 일어나고 : 나는 콜백을 저장 내 클래스에서

, 작업을 수행하고 내부 물건을 수행

Thread.new -> 성공/실패를 -> 표시를 모두 완료되면, 수행으로 -> 전화 콜백을 :

class ConnectionChecker 

    attr_reader :is_done 

    def initialize(&callback) 
    @callback  = callback 
    @thread_count = 0 
    @threads  = [] 
    @is_done  = false 
    end 

    def check_connectivity(host, port, timeout, ident) 
    @thread_count += 1 
    @threads << Thread.new do 

     status = false 
     pid = Process.spawn("nc -z #{host} #{port} >/dev/null") 

     begin 
     Timeout.timeout(timeout) do 
      Process.wait(pid) 
      status = true 
     end 
     rescue Process::TimeoutError => e 
     Process.kill('TERM', pid) 
     end 

     mark_as_done 
     #returnvalue for the callback. 
     [status, ident] 
    end 
    end 

    # one less to go.. 
    def mark_as_done 
    @thread_count -= 1 
    if @thread_count.zero? 
     @is_done = true 
     @callback.call(@threads) 
    end 
    end 
end 

이 코드는 그렇습니다. 시작 방법이 없다는 것을 알고 있으므로 즉시 전화를 걸면 좋을 것입니다.

그러나 나는이 2 개 라인 교체 할 때 :

@is_done = true 
    @callback.call(@threads) 

sleep while not check.is_done 

이 무한 루프되고, 다음

@callback.call(@threads) 
    @is_done = true 

맨 마지막 줄

에 있습니다. 디버깅은 콜백이 올바르게 호출 된 것을 보여줍니다. is_done의 값을 확인하면 실제로는 항상 false입니다. 저는 그것을 클로저에 넣지 않았기 때문에 왜 이런 일이 일어나고 있는지 궁금합니다.

콜백 자체도 비어있을 수 있습니다. is_donefalse 인 채로 있습니다 (따라서 잘못 잡힌 예외는 없습니다).

이 경우에는 마지막 스레드가 상태 실행 중임을 확인했습니다. 스레드 값을 묻지 않았으므로 여기서 멈추지 않습니다.

이 문제에 관한 모든 문서/정보? 또한, 그것의 이름은 괜찮을 것이다.

+0

뮤텍스를 사용하지 않으면 스레드 동작을 예측할 수 없습니다. 다른 루비 구현을 고려하십시오. – pguardiario

+0

@pguardiario 아, 완벽하게 고마워. 지금 내가 원하는대로 적절한 순서로 작업하고 있습니다. 어떤 점을 원하면 대답으로 답하십시오;) – thedanielhanke

답변

1

스레드 안전성을 보장하기 위해 뮤텍스를 사용하십시오.

+0

그걸 보지 못했습니다 : D – thedanielhanke