我正在使用inproc
和PAIR
来实现线程间通信,并试图解决轮询带来的延迟问题。如果我错了,请纠正我:轮询是不可避免的,因为普通的recv()
调用通常会阻塞,并且不能花费特定的超时时间。
在我当前的情况下,在N个线程中,每个N-1
工作线程都有一个主while循环。第N个线程是一个控制器线程,它将随时通知所有辅助线程退出。但是,工作线程必须使用带超时的轮询才能获取该quit
消息。这会引入等待时间,等待时间参数通常为1000ms
。
这是一个例子
while (true) {
const std::chrono::milliseconds nTimeoutMs(1000);
std::vector<zmq::poller_event<std::size_t>> events(n);
size_t nEvents = m_poller.wait_all(events,nTimeoutMs);
bool isToQuit = false;
for (auto& evt : events) {
zmq::message_t out_recved;
try {
evt.socket.recv(out_recved,zmq::recv_flags::dontwait);
}
catch (std::exception& e) {
trace("{}: Caught exception while polling: {}. Skipped.",GetLogTitle(),e.what());
continue;
}
if (!out_recved.empty()) {
if (IsToQuit(out_recved))
isToQuit = true;
break;
}
}
if (isToQuit)
break;
//
// main business
//
...
}
更糟糕的是,当主循环具有嵌套循环时,工作线程需要在嵌套循环的每一层中包含更多轮询代码。非常难看。
之所以选择ZMQ进行多线程通信,是因为它的优雅和摆脱线程锁定的潜力。但我从未意识到轮询开销。
使用常规互斥锁或std::atomic
数据操作时,我是否可以实现典型的延迟?我是否应该了解inproc
实际上是变相的网络通信模式,所以不可避免地会有一些延迟?