我有一个ROUTER / DEALER设置,两端都需要能够在可用时异步接收和发送数据。该模型几乎是0MQ的异步C ++服务器:http://zguide.zeromq.org/cpp:asyncsrv
客户端和服务器工作人员都会轮询,当有可用数据时,它们将调用回调。发生这种情况时,我正在另一个线程(!)中将数据放入std::deque
中。在每个永远轮询的线程中,我检查deque
(处于锁定状态),如果那里有项目,则将它们发送到指定的DEALER ID(该ID放在队列中)。
但是我不禁想到这不是惯用的0MQ。互斥锁可能是设计问题。另外,如果在两次轮询之间经过足够的时间(并且数据在deque
中累积),则内存消耗可能会非常高。
我能想到的唯一选择是每次我要发送数据并让它发送并退出时,将另一个DEALER线程连接到inproc
。但是,这意味着每个发送的数据项都有一个连接+一个套接字的构造和破坏,这可能不是理想的。
是否有惯用的0MQ方法来执行此操作?如果是,那是什么?
答案 0 :(得分:0)
我不完全了解您的设计,但确实了解您对使用锁的关注。
在大多数情况下,您可以重新设计代码,以使用zeromq PAIR套接字和inproc消除对锁的使用。
您真的需要std :: deque吗?如果不是这样,您可以只使用零个队列,因为它只是一个队列,您可以使用套接字从不同线程读取/写入该队列。
如果您确实需要双端队列,则将其封装到自己的线程中(一个类会很不错),并通过inproc套接字访问其API(推送等)。
就像我之前说的那样,我可能走错了路,但是在我遇到的99%的情况下,如果需要发信号,您总是可以使用一些ZMQ_PAIR / inproc完全删除锁。
答案 1 :(得分:-1)
0mq队列的缓冲区大小有限,可以控制。因此,内存问题将达到一定程度,然后发生数据丢失。因此,您可以考虑使用合并选项,仅将最新数据保留在队列中。
在单服务器和具有多线程的单机内通信的情况下,我建议使用“发布/订阅”模型,其中具有conflate选项,您在读取缓冲区后将立即接收新数据,而不必担心内存。并且它消除了阻塞队列的问题。
对于您的实现,您说的很对,这不是最好的设计,但这是不可避免的。我建议在问题Access std::deque from 3 threads回答您的问题时进行检查,但这可能不是最佳方法。