如何在同一个进程中操作多个 ZeroMQ Socket 类型?

Posted

技术标签:

【中文标题】如何在同一个进程中操作多个 ZeroMQ Socket 类型?【英文标题】:How to operate multiple ZeroMQ Socket Types In The Same Process? 【发布时间】:2017-03-07 14:48:25 【问题描述】:

我希望在我的嵌入式系统应用程序中使用 ZeroMQ 来促进 IPC,但是,我无法找到很多关于在同一进程中使用多个 0MQ 套接字类型的示例。

例如,假设我有一个名为“antenna_mon”的进程来监控天线。我希望能够向这个进程发送消息并获得回复 - 一个经典的 REQ-REP 模式。但是,我也有一个“cm”进程,它将配置更改发布给订阅者。我希望antenna_mon订阅天线配置更改 - PUB-SUB

我发现this example 在同一个进程中从多个套接字读取,但这似乎不是最佳的,因为现在你不再阻塞等待消息,你不断检查消息效率低下并重新进入睡眠状态。

以前有人遇到过这个问题吗?我只是想错了吗?也许我应该有两个线程 - 一个用于 CM 更改,一个用于 REQ-REP 服务?

我喜欢任何解决此类问题的见解或示例。

【问题讨论】:

我不太明白你的问题。在我看来,这取决于你的需要。或者我向你提出问题:cmantenna_mon之间的逻辑关系是什么?它们都是阻塞的还是非阻塞的?他们是否访问共享内存?无论如何,我认为您的问题与 ZeroMQ 无关,而只是您的需求。所以,分析你的需求,设计结构,然后编码。对我来说,如何操作多个socket是一个关于结构的问题,ZeroMQ是另一个关于代码的问题。 @Yuhui CM 是一个发布者,它在配置参数发生更改时通知订阅者。因此, antenna_mon 对配置更改通知感兴趣。但是,我还想查询有关他的状态的天线蒙,以从他那里获取统计信息。 ZeroMQ 适合这份工作吗?如果是这样,我该怎么做?指南中的所有示例都让每个进程只做一件事,但在现实生活中我希望天线蒙做多件事(成为配置更改的订阅者,同时也是查询的服务器) 您在下面的 cmets 中回答了您自己的问题。 zmq_poll() 完全符合您的要求。您还可以在轮询器中注册计时器,以便您可以定期“唤醒”线程以进行其他工作(不是由传入消息触发)。 @colini 谢谢,投票结果是我想做的。我需要更有耐心,在指南中走得更远。 【参考方案1】:

欢迎来到分布式计算的本质!

是的,一旦为多代理域组装了一个项目,就会有新的视角需要解决,其中不止一个进程可以工作并与各自的对等点进行通信。

从软实时系统或嵌入式系统设计经验中获得的知识库将在这里大有帮助。如果没有此类可用,则可能还会从 GUI 设计中选择一些相似之处,其中核心部件类似于轻量级 .mainloop() 调度程序,并且大部分工作都嵌入到循环轮询的 GUI 中- 设备和内部状态更改或外部 ​​MMI 事件被编组到事件触发的处理程序中。

ZeroMQ 基础架构为此类非阻塞、可控制轮询(可扩展、可变或自适应临时可调整轮询超时)提供了所需的所有工具,而不是克服给定的、设计定义的、往返持续时间控制器 .mainloop() )和与传输无关的异步操作的消息调度程序(具有线程映射的性能扩展和优先级调整)。

还需要什么?

嗯,只需想象力和大量的自律来坚持零复制、零共享和零阻塞设计准则。

剩下的都在你手中。

许多“学术”示例可能看起来微不足道和简化,以便仅说明当前讨论的内容,或者以某种狭隘的视角展示的功能。

在现实生活中并非如此。

例如,我的分布式 ML 引擎使用多个 PUSH/PULL 管道串联移动状态数据更新传输和预测预测 + 另一个 PUSH/PULL 用于远程键盘 + PUB/SUB 上的反向 .bind()/.connect(),以便将分布式代理的遥测数据轻松广播到远程集中操作的系统日志和一些额外的 PAIR/PAIR 管道,根据处理需要。

( nota bene: 应始终牢记,健壮且具有容错能力的系统应避免使用默认的 REQ/REP 可伸缩正式通信模式,因为存在非falling the pairwise-stepped REQ/REP dual-FSA into an unsalvageable deadlock.Do not hesitate to read more about this smart tool.的概率为零)

【讨论】:

我想我的问题是 - 在使用 PUB/ROUTER/PULL 的服务器的图表中 - 它是如何实际实现的?服务器是否有 3 个线程(一个用于处理 PUB 套接字,一个用于处理 ROUTER,一个用于处理 PULL)还是只是在所有三个线程中都使用 NOBLOCK 选项并在循环中检查它们? 其实我刚刚遇到这个:zguide.zeromq.org/cpp:mspoller - 我想我现在试试投票 猜猜最好的下一步是阅读伟大的 Pieter Hintjens 的著作 “Code Connected: Vol.1” 确实值得您花时间、流泪和汗水。我的代码永远不会没有 NOBLOCK,总是将套接字映射到具有不同 I/O 优先级的线程上,如果进入线程,可能会受益于零拷贝 PAIR/PAIR 或 PUSH/PULL over inproc:// 传输类(实际上是超快共享内存块)。你一定会喜欢的。 由于 mainloop 时间步长预算,到目前为止,我宁愿为每个目的都有一个专门的轮询器,我可以保证最大往返时间和最小持续时间,每个通道上每个 ".mainloop()" 循环的按比例加权的轮询延迟花费(每个消息传递和信令的每个循环保证的时间区分注意力份额I/O 通道(+ ZeroMQ 服务 I/O 线程池上的 .Context() 相对优先级映射)。

以上是关于如何在同一个进程中操作多个 ZeroMQ Socket 类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确处理 ZeroMQ.js 中的连接超时?

如何在 C++ 中使用 ZeroMQ 通信多个图像?

zeromq:如何防止无限等待?

zeromq为啥要cas

ZeroMQ 作业分配

我应该在 zeroMQ 程序初始化中添加睡眠以避免 heisenbugs 吗?