Zmq 上下文 - 我应该在新线程中创建另一个上下文吗?
Posted
技术标签:
【中文标题】Zmq 上下文 - 我应该在新线程中创建另一个上下文吗?【英文标题】:Zmq Context - Should I create another context in a new thread? 【发布时间】:2017-07-17 23:05:54 【问题描述】:我有几个使用我创建的共享 ZMQ 类的服务器应用程序。有时,这些服务器在处理请求时,需要向另一个 ZMQ 服务器发送消息。我对 ZMQ 还很陌生,所以我想确保自己理解正确。
处理服务器侦听器的类创建zmq::context_t
和zmq::socket_t
,并绑定套接字。这无限地在单独的线程上运行。当这个服务器需要在另一个函数中发送消息(完全从这个 ZMQ 类中删除)时,我是否需要在这里生成一个新的上下文并发送消息,或者我应该以某种方式将相同的上下文传递给这个类(在一个不同的线程),绑定一个新的套接字然后从那里去?
如果是前者,我用什么数字来初始化新上下文是否重要,或者 context( 1 )
可以吗?指南中有一部分说创建第二个上下文就像拥有多个 ZMQ 实例,我认为这并不重要,因为它仅用于发送文件然后关闭。但我可能错了?
【问题讨论】:
我不知道什么是更好的做法,但docs 说:» ØMQ 上下文是线程安全的,可以根据需要在尽可能多的应用程序线程之间共享,而无需任何额外的锁定调用者的一部分。«context
不应该是“消耗品/一次性”,它的实例化有很多开销。 IOthreads
的数量是另一回事——与实现最小延迟、阻塞状态稳健性和数据泵送性能(或基于性能等级的分组)更相关。请参阅 ZMQ_AFFINITY
用于将单个套接字映射到相应的 IOthread
-#(s)。高性能 + 低延迟代码只需将这些内部性调整到最大。 inproc://
传输类是 IO-less 并且可以使用 context( 0 )
的实例,它是一个内存映射。
@HenriMenke 您可能对 ZeroMQ 感兴趣,它是一个基本上无锁定的心理概念,因为底层服务会自动处理所有这些。 ZeroMQ 通过它的一些格言为分布式计算设定了一个非凡的标准——ZeroCopy、ZeroSharing、ZeroLocking、(几乎)ZeroLatency :o) 等——Pieter Hintjens 的书“Code Connected, Volume 1”。似乎是分布式系统中任何高级信令/消息传递的圣经。值得花时间和精力阅读它(也提供 pdf 格式)。
一开始我并没有意识到上下文#是IOThreads,认为它与上下文标识符有关,因为还有一个set IOThreads函数。但我现在正在修改我们的应用程序以使所有应用程序都使用指向主上下文的指针。感谢您的意见。
【参考方案1】:
简而言之:context
的单个实例,具有单个 I/O 线程,可能就是您所需要的。更详细:
Per the docs 上下文是线程安全的。请注意,最初的 0MQ sockets 通常不是(有一些更新的、起草的、设计成这样的)。
来自FAQ:
为了获得最佳性能,最佳 I/O 线程数是多少?
基本的启发式方法是在上下文中为将要发送和接收的每千兆位数据(聚合)分配 1 个 I/O 线程。 此外,I/O 线程数不应超过 (number_of_cpu_cores - 1)。
另外需要注意的是inproc://
传输类套接字must be created in the same context.
除非您要传输多个千兆位/秒,否则我建议您使用单个 I/O 线程为整个进程使用单个上下文。
同样作为准则,0MQ 上下文旨在“长期存在”。在应用程序的一次运行中创建/销毁多个上下文是不寻常的。这通常也适用于 0MQ 套接字。如果您要创建/销毁许多套接字,您可能采取了错误的方法。
【讨论】:
有新的线程安全套接字。但目前处于草稿阶段。以上是关于Zmq 上下文 - 我应该在新线程中创建另一个上下文吗?的主要内容,如果未能解决你的问题,请参考以下文章