我对ZMQ中1-n与多线程的概念效率感兴趣。
首先让我提出一个问题:
我有20个客户端和一个服务器。 (我会轻松使用推拉式插座,但如果答案随着rep,req,经销商,路由器的变化而变得很有兴趣)。
如果客户端有推送套接字并且服务器是拉,那么所有消息都会进入服务器上的单个拉出。 ZMQ会公平地将推送消息排队到服务器,并且可以为上下文提供初始化参数,以便使用的线程数。
但是引擎盖下发生了什么?它是否轮询它们之间的输入或多线程通信。是否可以从多线程中获得任何性能优势?
我可以看到制作上述系统的三种方法(20个客户端一台服务器)。
1)在服务器上使用一个拉式插座并推送每个客户端。
2)在服务器上使用20个插槽,使用zmq poll选择具有活动的插槽。客户端仍然各有一个推插座。
3)在服务器上使用20个拉线网络,每个线程在自己的线程内(例如20个线程)。客户端具有相同的20个插座(每个插座1个)。
据我所知,不使用选项1我会失去新加入的客户的动态特性而选项2会删除公平排队,但我只是对效率感兴趣。
这是我的问题,线程客户?或者只使用zmq 1-n?
答案 0 :(得分:0)
引擎盖下ZMQ正在使用诸如select(),epoll()之类的东西。这些后台线程运行zmqtp协议,该协议用于传输消息,实现模式等。您的程序使用zmq_send(),zmq_recv()以及zmq_poll()进行交互,zmq_poll()本身使用select ()。所以AFAIK一切都很有效率,当没有任何事情发生时,所有事情都会阻止,并且通过自己进行多线程处理并没有什么可以获得的。
这就是为什么IPC传输在Windows上无法运行的原因。 Windows上的管道没有select(),而* nix管道,套接字,文件等都只是文件描述符而select()对它们都有效。
Windows的这个功能是像Cygwin这样的主要PITA;他们在Windows上通过启动每个非套接字文件描述符的线程并轮询命名管道,串口等来实现POSIX的select()。因此,在Cygwin下,您可以创建管道并将它们包含在调用select( ),但是因此有一堆线程轮询底层的Windows管道,这是低效的。 ZMQ的作者选择不这样做。
如果在1)中为每个客户端服务所花费的时间比从客户端向服务器传输消息所花费的时间长,则只需要执行2)或3)。请记住,在所有这些下面是您的以太网NIC,无论如何一切都在经历。在服务器上拥有更多线程不会使以太网更快。