ZeroMQ REQ/REP on ipc://和并发 [英] ZeroMQ REQ/REP on ipc:// and concurrency
问题描述
我使用 REQ/REP 0MQ ipc://套接字实现了一个 JSON-RPC 服务器,我遇到了奇怪的行为,我怀疑这是由于 ipc://底层 unix 套接字不是真正的套接字,而是一个管道.
I implemented a JSON-RPC server using a REQ/REP 0MQ ipc:// socket and I'm experiencing strange behavior which I suspect is due to the fact that the ipc:// underlying unix socket is not a real socket, but rather a single pipe.
从文档来看,必须强制执行严格的 zmq_send()/zmq_recv() 交替,否则无序的 zmq_send() 将返回错误.
From the documentation, one has to enforce strict zmq_send()/zmq_recv() alternation, otherwise the out-of-order zmq_send() will return an error.
但是,我希望强制执行是针对每个客户端的,而不是针对每个套接字的.当然,对于 Unix 套接字,从多个客户端到服务器只有一个管道,因此服务器不会知道它正在与谁通话.两个客户端可以同时使用 zmq_send(),服务器会将此视为交替违规.
However, I expected the enforcement to be per-client, not per-socket. Of course with a Unix socket there is just one pipeline from multiple clients to the server, so the server won't know who it is talking with. Two clients could zmq_send() simultaneously and the server would see this as an alternation violation.
顺序可以是:
- 客户端:zmq_send()
- ClientB: zmq_send() :它会阻塞直到其他发送/接收完成?它会返回-1吗?(我怀疑它会使用 ipc://由于固有的低级问题,但使用 TCP 可以区分两个客户端)
- 客户端A:zmq_recv()
- 客户端B:zmq_recv()
那么 tcp://套接字呢?会同时工作吗?我应该使用其他锁定机制来解决这个问题吗?
so what about tcp:// sockets? Will it work concurrently? Should I use some other locking mechanism to work around this?
示例服务器:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <czmq.h>
int main(void)
{
zctx_t *zctx ;
void *zsocket_rpc;
printf ("rpcserver create context\n");
zctx = zctx_new();
printf ("rpcserver create socket\n");
zsocket_rpc = zsocket_new (zctx, ZMQ_REP);
if (!zsocket_rpc) {
fprintf (stderr, "zsocket_rpc is NULL\n");
exit(1);
}
zsocket_bind (zsocket_rpc, "ipc:///tmp/rpcserver");
for(;;) {
int rc;
char *msg = zstr_recv(zsocket_rpc);
printf ("rpcserver received %s\n", msg);
printf ("rpcserver sleep\n");
usleep(200000);
printf ("rpcserver send %s\n", msg);
rc = zstr_send(zsocket_rpc, msg);
if (rc < 0) {
fprintf (stderr, "rpcserver zstr_send returned %d\n", rc);
continue;
}
free(msg);
}
}
示例客户端(作为 ./rpcclient letter 启动):
Example client (launch as ./rpcclient letter ) :
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <czmq.h>
int main(int argc, char *argv[])
{
char msg[] = "A:MESSAGE 999";
zctx_t *zctx;
void *zsocket_rpc;
if (argc != 2) {
fprintf (stderr, "Usage: rpcclient letter\n");
exit(1);
}
zctx = zctx_new();
printf ("rpcclient new socket\n");
zsocket_rpc = zsocket_new (zctx, ZMQ_REQ);
if (!zsocket_rpc) {
fprintf (stderr, "zsocket_rpc is NULL\n");
exit(1);
}
printf ("rpcclient connect\n");
zsocket_connect (zsocket_rpc, "ipc:///tmp/rpcserver");
for (int cnt = 0; cnt < 1000; cnt++) {
int rc;
sprintf (msg, "%c:MESSAGE %03d", argv[1][0], cnt);
printf ("rpcclient send %s\n", msg);
rc = zstr_send(zsocket_rpc, msg);
if (rc < 0) {
fprintf (stderr, "rpcclient zstr_send returned %d\n", rc);
continue;
}
printf ("rpcclient sleep...\n");
usleep(200000);
char *reply = zstr_recv(zsocket_rpc);
printf ("rpcclient recv %s\n", reply);
free(reply);
}
}
推荐答案
谢谢 Pieter.我很抱歉,我今天进行的广泛测试证实,即使在 ipc://上有多个客户端,REQ/REPLY 也是坚如磐石的我认为问题已经结束.
Thank you Pieter. I apologize, the extensive tests I made today confirmed that the REQ/REPLY is rock solid even with multiple clients also on ipc:// I consider the question closed.
(问题是由于多个线程调用 RPC 函数而没有锁定......像往常一样)
(the problem was due to multiple threads calling RPC functions without locking... as usual)
这篇关于ZeroMQ REQ/REP on ipc://和并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!