为什么ZeroMQ没有使用其内部线程进行等待(在接收/发送时)?

时间:2014-04-23 06:08:16

标签: c++ multithreading sockets zeromq

从源代码中可以看出,当您拨打电话zsocket_new时,每个ZeroMQ套接字都会创建自己的内部线程(主要应用程序的天气是多线程的)。

这些内部线程正在运行select (0, &readfds, &writefds, &exceptfds, timeout ? &tv : NULL)的循环(第167-173行,select.cpp)。

现在,我不明白的是,尽管有这些内部线程的可用性,为什么像zmq_msg_recv这样的方法表现为阻塞调用,使你的主线程阻塞?

例如,请考虑以下代码

zctx_t *ctx = zctx_new();
void *router = zsocket_new(ctx, ZMQ_ROUTER);

int rc = zsocket_bind(router, "tcp://*:8080");
zframe_t *handle = zframe_recv(router);

它在你的调用线程上阻塞zframe_recv,在signaler.cpp的第207--212行等待,执行int rc = select (0, &fds, NULL, NULL, timeout_ >= 0 ? &timeout : NULL)

换句话说,对于单个ZMQ套接字,您有两个线程执行两个select()操作!!

如果你想使zframe_recv异步,你必须启动你自己的线程并在该线程内进行轮询或阻塞。

问题是 - 为什么ZMQ不使用这些内部线程进行选择,而不是强迫你创建另一个线程来读/写数据?

如果它只能适当地使用内部线程,它可能会成为一个非常好的演员模型 - 任何想法为什么它没有这样做?

1 个答案:

答案 0 :(得分:0)

  

现在,我不明白的是,尽管有这些内部线程的可用性,为什么zmq_msg_recv之类的方法表现为阻塞调用,使你的主线程阻塞?

ZMQ鼓励拥有一组单线程节点的网络。每个节点都有一组套接字,用于与其他节点通信。节点上的ZMQ上下文管理跨线路的实际消息传输,并有自己的线程集合来执行此操作,但鼓励您的节点逻辑是单线程的。

这可以被描述为“反应式编程”。入站邮件是事件,您可以通过发送出站邮件来响应这些事件。当您致电zmq_msg_recvzmq_poll时,意思是“等待下一个事件”并且正在阻止。

如果您发现无法使用单线程解决方案实现所需的节点逻辑,请考虑检查您的设计,以确保您的3线程节点不应该是3个单线程节点。