参考http://hintjens.wdfiles.com/local--files/main:files/cc1pe.pdf 第67页。
问题>我不明白为什么以下代码适用于多线程。根据我的理解,主线程在等待来自子线程的反馈时可以做不同的事情。
但是,在以下代码中,似乎在调用char *string = s_recv (receiver);
时阻止了step2,在调用char *string = s_recv (receiver);
时阻止了step3
根据我的理解,(step_i + 1)能够在从step_i收到信号之前做一些免费的事情。但是,正如您可以看到代码一样,step2和step3都被阻止,无法执行任何操作。为什么这是一个多线程代码?
谢谢
// Multithreaded relay
#include "zhelpers.h"
#include <pthread.h>
static void *
step1 (void *context) {
// Connect to step2 and tell it we're ready
void *xmitter = zmq_socket (context, ZMQ_PAIR);
zmq_connect (xmitter, "inproc://step2");
printf ("Step 1 ready, signaling step 2\n");
s_send (xmitter, "READY");
zmq_close (xmitter);
return NULL;
}
static void *
step2 (void *context) {
// Bind inproc socket before starting step1
void *receiver = zmq_socket (context, ZMQ_PAIR);
zmq_bind (receiver, "inproc://step2");
pthread_t thread;
pthread_create (&thread, NULL, step1, context);
// Wait for signal and pass it on
char *string = s_recv (receiver);
free (string);
zmq_close (receiver);
// Connect to step3 and tell it we're ready
void *xmitter = zmq_socket (context, ZMQ_PAIR);
zmq_connect (xmitter, "inproc://step3");
printf ("Step 2 ready, signaling step 3\n");
s_send (xmitter, "READY");
zmq_close (xmitter);
return NULL;
}
int main (void)
{
void *context = zmq_ctx_new ();
// Bind inproc socket before starting step2
void *receiver = zmq_socket (context, ZMQ_PAIR);
zmq_bind (receiver, "inproc://step3");
pthread_t thread;
pthread_create (&thread, NULL, step2, context);
// Wait for signal
char *string = s_recv (receiver);
free (string);
zmq_close (receiver);
printf ("Test successful!\n");
zmq_ctx_destroy (context);
return 0;
}
答案 0 :(得分:2)
我阅读它的方式,示例代码仅显示如何让主线程(step3)知道其他两个线程已经创建并正确连接。来自step1的信号经过step2到step3,所以一旦到达那里,所有信号都已准备就绪。这应该很快发生。
当线程完成后,您可以传递一条新消息,而不是加入它们,而不是DONE
。完成后,步骤1发送此消息。完成后,每个其他步骤开始等待此消息,当它收到消息时,将其传递给下一步。当step3收到DONE
消息时,所有线程都已完成。
或者您可以使用此类消息来累积每个线程的工作结果。
不是等待对象,而是开始同步接收消息。您可以发送消息,而不是通知。
因此,如果我理解正确,多线程工作应该发生在这些同步消息之间。
修改
似乎在调用
时阻止了step2s_recv
这个例子很好,因为除了等待READY
消息之外,step2没有什么用处。如果在您的用例中线程必须工作并定期检查是否有消息等待它,它可以使用zmq_recv
标志以非阻塞模式调用ZMQ_DONTWAIT
,以检查消息是否已经到了。