2012-09-07 2 views
2

내가 아주 간단한 스레드 루프ZeroMQ 컨텍스트의 파괴는 ETERM에 폴러가 발생하지만

public void ClientLoop(object AContext) 
{ 
    var context = (ZMQ.Context) AContext; 

    Socket client = CreateServerSocket(context); 

    while (true) 
    { 
     try 
     { 
      Context.Poller(requestTimeout*1000, client); 
     } 
     catch (Exception e) 
     { 
      if (e.Errno == ETERM) 
      { 
       //Catch a termination error. 
       Debug.WriteLine("Terminated! 1"); 
       return; 
      } 
     } 
    } 
} 

그리고 클라이언트 소켓이 생성됩니다 다음

public void Dispose() 
{ 
    _context.Dispose(); 
} 

처럼 보이는 처분이 계속되지 않습니다 linger는 0으로 설정되고 poller는 핸들러 세트로 설정됩니다. 소켓은 요청 소켓이기도합니다.

처분이 호출되면 폴러를 제외하고 try except 블록으로 분류됩니다. 그러나 처분이 끝난 후에도 나는 그렇게 생각하지는 않았다. 이것은 ZGuide가 컨텍스트와 소켓의 파괴를 처리하는 방법이지만이 경우에는 작동하지 않는 것 같습니다.

내가 무엇을 놓쳤는가?

답변

5

그러나 처분이 끝난 후에도 계속 그렇게 생각하지는 않았습니다.

전화 걸기/블록 호출을 의미합니까? 이는 스레드에서 돌아 오기 전에 클라이언트 소켓을 닫지 않았기 때문입니다. 다만 차단에서 소켓 폐쇄를 방지 함 - 0으로 링거를 설정하는 것만으로는 충분하지 않습니다

 if (e.Errno == ETERM) 
     { 
      //Catch a termination error. 
      Debug.WriteLine("Terminated! 1"); 
      client.Close(); 
      return; 
     } 

(아래 내 구문이 잘못 될 수 있지만 당신은 아이디어를 얻을). _context.Dispose()가 차단되지 않도록 작업자 스레드의 소켓을 닫아야합니다. ZGuide 컨텍스트와 소켓의 파괴를 처리하기 위해 말한다 방법

은 ... 음

입니다 - 그 사실이지만 문서에서 중요한 규정이있다 :

우리 다음 장에서 멀티 스레딩을하게 될 것입니다.하지만, 경고에도 불구하고 안전하게 걸을 수 있기 전에 일부는 실행하려고하기 때문에, 아래는 멀티 스레드 ØMQ 어플리케이션에서 깨끗한 종료를 만드는 빠르고 쉬운 안내서입니다.

나중에 문서에서는 kill 신호를 수신하는 각 스레드에 전용 소켓을 사용하여 클린 종료를 수행하는 방법에 대해 설명합니다. 유사한 작업을 수행하여 작업자 스레드를 향상시키는 것을 고려하십시오. 이렇게하면 각 스레드에게 메시지를 보냄으로써 각 스레드가 스스로 종료되도록 요청할 수 있습니다. 각 스레드는 실행 루프를 빠져 나 가면서 소켓을 깨끗하게 닫고 종료합니다. 모든 스레드가 종료되면 오류없이 문맥을 안전하게 처리 할 수 ​​있습니다.

+0

굉장한 작품입니다. 초기 문제는 내 고객이해야 할 때 마감하지 않고, 사용할 다음 디자인 패턴에 대한 제안을하기까지했습니다. 고맙습니다. – Jason

+0

멋진 설명.! – hims056

+0

닫기 소켓이 열쇠입니다. 단절만으로는 충분하지 않습니다. 소켓을 닫으면 처리가 정상적으로 수행 되나? – liang