用C ++编写我有一个线程,它使用zmq poll方法来发现何时有新事件要处理,哪个工作正常。我想要的是这个线程退出,同时在没有更多事件预期时很好地清理。
而不是无限循环我可以在那里放置一个条件,但它需要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 :(得分:4)
经常提到你可以破坏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];
答案 1 :(得分:1)
不要中断轮询 - 向线程发送指示其清理并退出的消息。