2016-06-29 13 views
2

기본적으로 나는이 문제가 있습니다. 첫 번째 클래스, 즉 서버는 클라이언트가 .connect() 일 때까지 기다리고 클라이언트가 연결되면 서버는 클라이언트에 데이터를 보냅니다.Client가 .connect()를 기다리는 스레드를 중지하는 방법은 무엇입니까? <p></p> 내가 ZMQ 다른 프로그램에 데이터의 일부 조각을 게시 할 <strong><code>PUB/SUB</code></strong> 공식적인 패턴을 사용하기 위해 사용

저는 ZMQ REQ/REP을 사용하여 서버와 클라이언트를 동기화합니다.

Server.py입니다 :

class PublishThread (threading.Thread): 
def __init__(self): 
    threading.Thread.__init__(self) 
    socketPub.bind("tcp://127.0.0.1:4002") 
    syncservice.bind('tcp://127.0.0.1:5001') 
def run(self): 
    while True: 
     subscribers = 0 
     topic = b"PHONEBOOK" 
     while subscribers < 1: 
      # Here we wait for client to connect. If the client doesn't 
      #connect, this is where this thread will "hang" 
      syncservice.recv() 
      # Send response to client 
      syncservice.send(b'') 
      subscribers += 1 

     socketPub.send_multipart([topic, data1]) 
     subscribers = 0 

Q1 : 내 프로그램을 종료 할 때가 어떻게이 스레드를 중지 할 수 있습니다?
스레드가 실행 중이고 클라이언트를 기다리고 있기 때문에 프로그램을 종료하려고 할 때 프로그램이 "중단"됩니다.
질문 2 : 어떻게 구현하는 것이 가장 좋을 것이라고 생각하십니까?
질문 3 :REQ/REP 이외의 다른 방법이 있습니까?

+0

응답하지 않는 코드에 시간 초과 추가 –

+0

이 코드는 고품질 질문을 게시하는 ** StackOverflow 승격 된 MCVE 메서드 **와 거리가 다릅니다. 텍스트 상태 (cit. :) "... 서버 ... 클라이언트 ... REQ/REP"하지만 이러한 요소는 코드에 없습니다. ** 커뮤니티에 진단 및 수정을 요청하는 문제를 재현 할 수있는 서버 및 클라이언트 **에 대한 완전한 대표 MCVE를 포함하도록 질문을 업데이트하십시오. ** 이것은 모든 종류의 MCVE 관련 문제를 건설적으로 해결하고 토론하기 위해 StackOverflow 선호 방식입니다 **. 어쨌든 **이 위대한 지식의 커뮤니티 **에 오신 것을 진심으로 환영합니다. – user3666197

답변

0

스레드를 중지하는 가장 좋은 방법은, 다음, 부울 거짓 값으로 초기화 된 shutdown 속성을 생성, 종료 메시지를 보내 while 루프 (서버를 실행할 수있는 상태로 설정하는 것입니다 while !shutdown: 설정) 서버가 클라이언트로부터 종료 요청을 받으면 shutdown 속성의 값을 true로 수정하여 while 루프를 중지하고 스레드를 종료합니다.

+0

나는 그것을 시험해 보았지만 문제는 Thread가 멈추고 Client를 기다리는 것이다. 따라서 클라이언트가 연결하지 않으면 스레드는 멈추고 syncservice.revc()를 기다립니다. 그래서 내가 프로그램을 닫으면, Server는 여전히 참을 때마다 반복하지 않을 것이기 때문에 기다릴 것입니다. – koci

+0

위의 대답에 게시 된 바와 같이, 장난감은 좀 더 복잡한 방식으로 작동합니다. ZeroMQ가 MCVE 코드에서'.recv()'와'.send()'를 호출하면 다행히 ** 블로킹 **이됩니다. 사실, 이것은 대부분의 프로덕션 급 소프트웨어 설계에서 좋은 설계 방식이 아니며, 스레드 레벨 소프트 시그널링이나 하드 SIG_KILL 시그널링이 성공하지 못하게합니다. 실제 블로킹은 다른 위협 (.Socket() 인스턴스에 속한 .Context() 인스턴스 (반드시 중앙의 세션 일 필요는 없음)의 실행 상태에서 숨겨집니다. . 플러스 REQ/REP 교착 상태. – user3666197

0

ZeroMQ는 메시징 및 신호 기능을 "그냥 사용"할 수있는 스마트 분산 응용 프로그램을위한 매우 강력한 도구 집합입니다 (어쨌든 do not hesitate to follow the book을 알고있는 경우).


A1

: 첫째, 당신은 여전히 ​​독립적으로 내부/외부 차단제의 당신의 스레드 코드에 대한 제어를 유지할 수 있도록, 비 차단, 비동기 모드에서 코드 단위를 설계 시작해야합니다. 교훈 1 번으로, 하나는 바로 알몸 .recv()를 사용하는 것을 잊지하는 정신적로 전환 zmq.NOBLOCK 및/또는 루프 제어 .poll(nMSECs) 모든 ZeroMQ 래퍼가 pyzmq는이 같은 편안함이 필요하지 않습니다 (, 이 보너스로 이익을 얻으십시오).


A2 : 경험적으로, 하나 ZeroMQ -patterns 모든 스레드 코드 단위의 코어 로직에 추가 여러 추가 SIGDIAG 메시지를 사용할 수있다. 이는 테스트 및 임의의 종류의 내부 설정에서의 임시 변경에 모두 도움이됩니다. 코드 단위에 대한 CLI 인터페이스를 효과적으로 추가하는 것은 시원한 부산물입니다. 그렇지 않습니까?) 및/또는 실.


A3: 오 확실하다. 사람이 REQ/REP 형식적인 의사 소통 패턴이 맞다고 생각할 때마다 서적을 다시 확인하고 생존 할 수 있도록 코드를 다시 설계하십시오. REQ/REP 비 동기화 배포에서 자신을 얻을 수 없음 - FSA - 조용히 침입 한 후 스테핑 동기화가 해제 된 상태. 많은 게시물이이 주요 문제를 언급합니다.


에필로그 : 스레드에서 ZeroMQ 소켓 인스턴스를 공유하지 않는 것이 좋습니다.

+0

안녕하세요. 내 실수를 고쳐 주셔서 고맙습니다. 그건 고의적이지 않았습니다. 필자는 철자를 다시 수정했습니다 (강력하고 우아하며, 모두 L이 1 개, 2 개가 아닙니다). 귀하의 편집 메시지는 다시 부적절하며 긍정적 인면에서 편집 내용을 보았을 때 정직한 실수를 저지르는 데 약간의 여유를 두었습니다. 내 편집 내용은 다시 작업에 대한 공격이 아닙니다. 모두 제일 좋다. – halfer

+0

** 감사합니다 **. 이것은 실제로 내 잘못이었습니다. 복사/붙여 넣기를 사용했습니다. 두뇌는 꺼졌습니다 : o) ** 당신이 ML/NLP 렉서를 사용하기를 희망합니다. ** 모든 나의 역사적인 죄와 문법 오류를 직접 읽을 필요가 없습니다 : o) 주말을 즐겨라. – user3666197

+0

좋아, 고마워! ':-)' – halfer