【问题标题】:Using ZMQ for bidirectional inter-thread communication使用 ZMQ 进行双向线程间通信
【发布时间】:2017-05-13 21:18:37
【问题描述】:

我是 ZeroMQ 的新手。在过去的几个月里,我一直在阅读文档并尝试使用该库。我目前正在开发一个多线程 c++ 应用程序,并希望使用 ZeroMQ 而不是互斥锁在我的主线程和它的一个子线程之间交换数据。

子线程正在处理与外部应用程序的通信。因此,我需要在主线程与其子线程之间进行排队/套接字。一个用于传出消息,一个用于传入消息。

我应该使用哪个 zmq 套接字来实现这一点。

提前致谢

【问题讨论】:

标签: zeromq


【解决方案1】:

通过从使用共享内存和互斥体转向使用 ZeroMQ,您正在进入 Actor 模型编程领域。

在我看来,这是一件相当不错的事情。但是,有一些事情需要注意。

  1. 不再需要互斥锁的唯一原因是您正在复制数据,而不是共享它。 “成本”是复制大量数据比锁定指向共享数据的互斥锁花费的时间要长得多。因此,与使用共享内存/互斥锁的等效程序相比,您最终可以得到一个看起来像狗一样运行的漂亮 Actor 模型程序。
  2. 需要注意的是,在具有多个 CPU 的 Intel Xeon 等复杂架构上,访问共享内存所花费的时间可能与复制它的时间一样长。这是因为这可能(取决于你有多幸运)意味着跨 QPI 总线的事务。 Actor 模型编程非常适合 NUMA 硬件架构。现代 Intel 和 AMD 架构部分/根本上是 NUMA,但它们在 QPI/Hypertransport 上运行的协议“伪造”了 SMP 环境。
  3. 我会尽可能避免使用 ZMQ_PAIR 套接字。它们不能跨网络连接工作。这意味着,如果出于任何原因,您的应用程序需要跨多台计算机进行扩展,您必须重新编写代码。但是,如果您从一开始就使用不同的套接字类型,那么您的应用程序的扩展只不过是重新部署您的代码,而不是更改它。仅供参考 nanomsg PAIR 没有此限制。
  4. 暂时不要假设 Actor 模型编程能够解决您的所有问题。它带来了一整套自己的问题。您仍然可以死锁、活锁、自旋锁等。Actor 模型程序的问题在于,这些问题可能会在您的代码中潜伏多年并且永远不会发生,直到有一天网络变得有点忙并且-bam-您的程序停止运行...
  5. 但是,Actor 模型编程的发展称为“通信顺序过程”。这并不能解决这些问题,但是如果您编写程序时遇到这些问题,它们肯定会每次都发生。所以你在开发和测试过程中发现了问题,而不是五年后。它还有一个过程演算,即您可以在编写单行代码之前通过代数证明您的设计没有问题。 ZeroMQ 不是 CSP。有趣的是,CSP 正在卷土重来——Rust 和 Go 语言都使用 CSP。但是,他们不会跨网络连接执行 CSP - 这都是进程内的东西。 Erlang 也执行 CSP,AFAIK 跨网络连接执行。
  6. 假设您已阅读有关 CSP 的所有内容并且仍将使用 ZeroMQ,请仔细考虑您计划通过 ZeroMQ 套接字发送的内容。如果它们都在同一台机器上的一个程序中,那么发送例如整数数组的副本就可以了。在接收端,它们仍然可以解释为整数。但是,如果您希望通过 ZMQ 套接字将数据发送到另一台计算机,那么值得考虑某种序列化技术。 ZeroMQ 传递消息。为什么不让这些消息成为来自对象序列化器的字节流呢?然后,您可以保证收到的消息在反序列化后,在接收端意味着适当的东西,而不必解决字节顺序等问题。
  7. 我最喜欢的序列化程序包括 Google 协议缓冲区。它与语言/操作系统无关,为异构系统提供了许多选项。 ASN.1 是另一个非常好的选择,它可以用于大多数重要的语言,并且它具有丰富的有线格式(包括 XML 和现在/即将推出的 JSON,它提供了一些有趣的互操作选项),并且有约束(Google PBufs 不做的事情),但如果一个人想要真正好的工具,它确实会花钱。几乎任何东西都可以理解 XML,但它很臃肿。基本上,值得选择一个不会束缚您在任何地方都使用 C# 或 Python 的工具。

祝你好运!

【讨论】:

  • 一如既往,@bazza,每个分布式计算架构师都必须牢记的设计方面的精彩清单。 干得好!
  • 感谢您的详细解答。我将阅读更多关于 CSP 的内容,看看它是否可以改进我的架构。
猜你喜欢
  • 2023-03-07
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 2015-01-19
  • 2021-11-10
  • 1970-01-01
相关资源
最近更新 更多