【发布时间】:2020-03-07 05:00:14
【问题描述】:
我正在使用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 实际上是一种伪装的网络通信模式,因此一些延迟是不可避免的?
【问题讨论】:
标签: c++ multithreading networking zeromq latency