일부 스레드를 보유하고있는 클래스를 생성하고, 마지막으로 콜백 메소드를 호출하는 것이 현재의 목표입니다.이 도로에서는 특별한 것이 없습니다.루비 스레드 콜백 이상한 동작
내 실험 클래스는 주어진 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_done
은 false
인 채로 있습니다 (따라서 잘못 잡힌 예외는 없습니다).
이 경우에는 마지막 스레드가 상태 실행 중임을 확인했습니다. 스레드 값을 묻지 않았으므로 여기서 멈추지 않습니다.
이 문제에 관한 모든 문서/정보? 또한, 그것의 이름은 괜찮을 것이다.
뮤텍스를 사용하지 않으면 스레드 동작을 예측할 수 없습니다. 다른 루비 구현을 고려하십시오. – pguardiario
@pguardiario 아, 완벽하게 고마워. 지금 내가 원하는대로 적절한 순서로 작업하고 있습니다. 어떤 점을 원하면 대답으로 답하십시오;) – thedanielhanke