multithreading - ZeroMQ:如何处理 ZeroMQ 节点中与消息无关的异步事件?

标签 multithreading asynchronous zeromq distributed-computing distributed-system

假设我有一个带有 ZeroMQ 接口(interface)的节点(进程、线程等),比方说一个 REP 套接字。这意味着我有一个无限主循环,它在 zmq_recvzmq_poll 函数中休眠。

现在该节点还应该从另一个异步事件接收数据。例如,想象一下键盘按钮按下事件或切换 GPIO 引脚或计时器到期。在等待这些事件时,执行也必须休眠。

应如何编写主循环,使其在任一类型的事件(即消息的接收和异步事件的发生)上唤醒?

我可以想到两种解决方案:

首先,轮询循环,其中以非阻塞方式检查两个事件,我每隔几毫秒运行一次循环。这在处理负载方面似乎不理想。

其次,我将两个事件的阻塞代码移到单独的线程中。相反,在主循环中,我睡在一个信号量(或条件变量)上,它​​由任一事件的发生发布。这就是我在传统应用程序中采用的方式,但是 ZeroMQ Guide Pieter Hintjens 写的非常明确使用信号量:

Stay away from the classic concurrency mechanisms like as mutexes, critical sections, semaphores, etc. These are an anti-pattern in ZeroMQ applications.

那怎么办?这里的最佳做法是什么?

最佳答案

根据您的操作系统,系统中的大多数事件都是通过一些文件描述符准备好读取而生成的。这通常是它在 Linux、Unix 等系统上的工作方式。例如,键盘输入通过 STDIN 输入。当然,任何描述的文件描述符都可以包含在 ZMQ 轮询中。

如果事件不是通过可在 ZMQ 轮询中使用的文件描述符引发的(例如,Windows 上的串行端口准备好读取),我通常使用线程将事件转换为通过 ZMQ 发送的消息 socket 。效果很好。变得不可移植,但这是不可避免的。

GPIO 可能更难。如果它没有得到某个将 ISR 集成到操作系统驱动程序堆栈中的驱动程序的支持,那么您将不得不轮询它。

关于multithreading - ZeroMQ:如何处理 ZeroMQ 节点中与消息无关的异步事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50856746/

相关文章:

c++ - 事件/任务队列多线程 C++

javascript - 图像预加载器如何工作?

linker - zmq.hpp - 未定义引用 `zmq_poll'

java - 使用 CyclicBarrier 的 Barrier.await() 之后线程没有继续进行

c++ - C++ 11 原子对象的执行也是原子的吗?

django - 如何从基于 Django 的站点管理任务的停止或重新启动?

c++ - 游戏逻辑的异步屏幕更新,C++

python - 为什么ZMQ路由器有时会丢失消息?

bash - 如何修复 "missing some pkg-config macros"错误?

iphone - dispatch_group_wait 与 GCD