ZeroMQ:如何使用Inproc减少多线程通信延迟?

我正在使用inprocPAIR来实现线程间通信,并试图解决轮询带来的延迟问题。如果我错了,请纠正我:轮询是不可避免的,因为普通的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实际上是变相的网络通信模式,所以不可避免地会有一些延迟?

dongshaobo 回答:ZeroMQ:如何使用Inproc减少多线程通信延迟?

上面发布的陈述(一个假设):

  

“ ...一个普通的recv()呼叫通常会阻止,并且无法执行特定的超时操作。”

不正确:
普通的.recv( ZMQ_NOBLOCK )通话永远不会 “阻止”
一个普通的.recv( ZMQ_NOBLOCK )呼叫可以得到修饰,以模仿 “特定超时”

上述声明(一个假设):

  

“ ... 具有 可以使用超时轮询 ... 引入了延迟,延迟参数通常为 1000ms

不正确:
-不需要使用超时的轮询
-较少的一个不需要设置1000毫秒的代码-“注入”延迟,显然只花费在没有新消息的状态上

  

Q “使用常规的mutexstd::atomic数据操作时,我是否能够实现典型的延迟?” >

是的

  

Q “我是否应该了解inproc实际上是一种变相的网络通信模式,因此不可避免地存在一些延迟?”

不。 inproc -transport-class是所有此类中最快的,因为它基本上没有协议/没有栈,并且与最终的快速指针机制(如双指针)有更多关系-end ring-buffer指针管理。


最佳下一步:

1)
重构代码,以便始终利用零等待时间的 { .poll() | .recv() } 方法,并对其进行了适当的修饰两者{事件-|特定于事件的循环。

2)
如果然后愿意从智能环路检测的周转时间中剃除最后几个[us],则可以着重改善 Context() -实例将其设置为与大量nIOthreads > N一起“在幕后”工作。

可选3)
对于几乎是硬实时系统的设计,人们可以最终利用确定性驱动的Context()线程和特定于套接字的映射将这些执行程序映射到特定的,不重叠的CPU-上。核心(使用精心制作的相似性贴图)


已经在代码中设置了1000 [ms],没有人会抱怨要花那1000 [ms]来等待自己(自己)自己编码的超时。没有任何借口。

不要责怪ZeroMQ的行为,这些行为是从API的应用程序端编码的。

从不。

本文链接:https://www.f2er.com/3123819.html

大家都在问