2014-01-24 30 views
1

用C++編寫我有一個線程使用zmq輪詢方法來發現什麼時候有新事件要處理,這很好。我想要的是當這個線程退出的時候,如果沒有更多的事件發生,那麼清理很好。如何最好地中斷清理和終止zeroMQ輪詢方法

而不是無限的while循環我可以在那裏放置一個條件,但它需要REQUEST_TIMEOUT_MS去那裏。所以我的問題是,打斷程序退出的最佳方法是什麼?

void * Requester::recieve_thread(void *arg) { 

    zmq::socket_t * soc = (zmq::socket_t *) arg; 

    zmq::pollitem_t items[] = { { *soc, 0, ZMQ_POLLIN, 0 } }; 

    while (1) { 
     zmq::poll(&items[0], 1, REQUEST_TIMEOUT_MS); 

     if (items[0].revents & ZMQ_POLLIN) { 

      // process the event 
     } 
    } 

    // clean up 
} 

回答

0

不要中斷輪詢 - 向線程發送消息指示它清理並退出。

2

經常提到你可以銷燬zmq上下文,任何共享這個上下文的東西都會退出,但是這會產生一個噩夢,因爲這會刪除套接字對象,你現有的代碼必須盡最大努力避免一個雷區死指針。

試圖關閉套接字不起作用,或者是因爲它們不是線程安全的,最終會導致崩潰。

答案:最好的方法是按照ZeroMQ指南的建議,通過多線程進行任何使用;使用zmq套接字而不是線程互斥/鎖/等。

Requester::Requester(zmq::context_t* context) 
{ 
    m_context = context; 

    // Create a socket that you'll use as the interrupt-event receiver 
    // I'm using a random address and an inproc socket (inprocs need to share a context) 
    snprintf(m_signalStopAddr, sizeof(m_signalStopAddr)/sizeof(*m_signalStopAddr), "inproc://%lx%x", (unsigned long)this, rand()); 
    m_signalStop = new zmq::socket_t(m_context, ZMQ_PAIR); 
    m_signalStop->bind(m_signalStopAddr); 
} 

// Your thread-safe poll interrupter 
Requester::interrupt() 
{ 
    char dummy; 
    zmq::socket_t doSignal(m_context, ZMQ_PAIR); 
    doSignal.connect(m_signalStopAddr); 
    doSignal.send(&dummy, sizeof(dummy)); 
} 

void * Requester::recieve_thread(void *arg) 
{ 
    zmq::socket_t * soc = (zmq::socket_t *) arg; 
    zmq::pollitem_t items[] = 
    { 
     { *soc, 0, ZMQ_POLLIN, 0 }, 
     { *m_signalStop, 0, ZMQ_POLLIN, 0 } 
    }; 

    while (1) 
    { 
     zmq::poll(items, 2, REQUEST_TIMEOUT_MS); 
     if (items[1].revents & ZMQ_POLLIN) 
     { 
      break; // exit 
     } 

     if (items[0].revents & ZMQ_POLLIN) 
     { 
      // process the event 
     } 
    } 

    // Cleanup 
} 

zmq::context_t* m_context; 
zmq::socket_t* m_signalStop; // Don't forget to delete this! 
char m_signalStopAddr[100];