使用ZMQ进行双向线程间通信

时间:2017-03-29 18:46:19

标签: zeromq

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

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

我应该使用哪个zmq套接字来实现此目的。

提前致谢

1 个答案:

答案 0 :(得分:6)

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

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

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