问题
I am trying to use zeroMQ
as a way to implement a messaging system between multiple threads. I tried the code below but it doesn't work; in the specific the call to zmq_recv
in each thread doesn't wait/block for any message to be executed.
Can you help me with this piece of code?
I am using Linux OS and gcc
Best Regards
AFG
static void *
worker_routine (void *context) {
// Socket to talk to dispatcher
void *receiver = zmq_socket (context, ZMQ_REP);
zmq_connect (receiver, "inproc://workers");
while (1) {
zmq_msg_t request;
zmq_msg_init( &request );
zmq_recv( receiver, &request, 0 );
printf ("Received request\n");
// Do some 'work'
usleep (1000);
// Send reply back to client
zmq_send (receiver, &request, 0);
}
zmq_close (receiver);
return NULL;
}
int main (void) {
void *context = zmq_init (1);
void *clients = zmq_socket (context, ZMQ_REP);
zmq_bind (clients, "inproc://workers");
int thread_nbr;
for (thread_nbr = 0; thread_nbr < 5; thread_nbr++) {
pthread_t worker;
pthread_create (&worker, NULL, worker_routine, context);
}
zmq_close (clients);
zmq_term (context);
return 0;
}
回答1:
Both sockets are REP. What you want is REQ + REP.
回答2:
You're shutting down the socket and ZeroMQ right after you're creating the threads. They probably don't have time to reach a blocking state, and if they did, they would fail as soon as you destroy the zmq context. From the zmq_term man page:
Context termination is performed in the following steps:
Any blocking operations currently in progress on sockets open within context shall return immediately with an error code of ETERM.
回答3:
Firstly, as @sustrik noted you need to use REQ
and REP
, both the main thread and the worker threads cannot be REP
.
Secondly, you need to provide some sort of blocking loop in your main thread:
int main (int argc, char **argv)
{
void *context = zmq_init (1);
void *clients = zmq_socket (context, ZMQ_REP); // use ZMQ_REQ on the clients
zmq_bind (clients, "inproc://workers");
int thread_nbr;
for (thread_nbr = 0; thread_nbr < 5; thread_nbr++) {
pthread_t worker;
pthread_create (&worker, NULL, worker_routine, context);
}
while (TRUE)
{
// worker thread connected asking for work
zmq_msg_t request;
zmq_msg_init (&request);
zmq_recv (clients, &request, 0);
zmq_msg_close (&request);
// do whatever you need to do with the clients' request here
// send work to clients
zmq_msg_t reply;
zmq_msg_init_data (&reply, "Reply", 5, NULL, NULL);
zmq_send (clients, &reply, 0);
zmq_msg_close (&reply);
}
zmq_close (clients);
zmq_term (context);
return 0;
}
来源:https://stackoverflow.com/questions/5476308/inter-thread-comunication-using-zeromq-messages