我正在用C++编写一个分支聊天服务器,每个传入的客户端都有自己的进程。服务器与客户端的交互是通过普通套接字完成的,其中ZeroMQ套接字处理消息队列和进程间通信。基本问题是,当服务器派生新的客户端时,客户端的进程有上下文的副本(这就是fork所做的,对吧?),所以当它将套接字与上下文绑定时,其他客户端都不知道套接字。长话短说:如何让每个客户端线程具有相同的上下文,以便它们可以通过ZeroMQ相互通信?
我已经研究了在进程之间共享上下文的各种方法,到目前为止,我只找到了this one。问题是1)它使用一个线程池,据我所知,只创建了5个线程;这个服务器需要支持至少256个线程,因此将至少有那么多线程,2)它使用ZeroMQ与客户端对话和后端任务;我仅限于将ZeroMQ用于后端。
我看过fork邮件列表,有一条消息说ZeroMQ ()与ZeroMQ的工作方式是正交的。这是否意味着我不能在派生的子进程之间共享上下文?如果是这样的话,我如何在多个进程之间共享上下文,同时记住至少支持256个客户端和仅将ZeroMQ用于后端的要求?
编辑:清除了线程/进程的混乱。真对不起。
EDIT2:我也喜欢在线程上派生的原因是,我习惯了让主进程接受传入的套接字连接,然后派生,将新的套接字提供给子进程。我不确定如何以线程的方式做到这一点(没有真正的实践,但也不完全超出我的能力范围)
EDIT3:所以,开始用线程重写它。我想这是唯一的办法了?
EDIT4:为了进一步说明,到服务器的传入连接可以是TCP或UDP,并且当客户端连接时,我必须处理它是哪种类型,所以我不能使用ZeroMQ套接字来侦听。
发布于 2013-04-20 11:43:32
上下文共享
在链接的示例代码中共享ZMQ上下文的原因是,服务器(main())使用inproc套接字与工作者(worker_routine())通信。Inproc套接字不能相互通信,除非它们是从相同的ZMQ创建的,即使它们位于相同的进程中。在您的情况下,我认为没有必要共享它,因为不应该使用inproc套接字。因此,您的代码可能如下所示:
void *worker_routine (void *arg)
{
// zmq::context_t *context = (zmq::context_t *) arg; // it's not necessary for now.
zmq::context_t context(1); // it's just fine to create a new context
zmq::socket_t socket (context, ZMQ_REP);
// socket.connect ("inproc://workers"); // inproc socket is useless here.
socket.connect("ipc:///tmp/workers"); // need some sockets who can cross process.
// handling code omitted.
}
int main ()
{
// omitted...
// workers.bind ("inproc://workers"); // inproc socket is useless here.
workers.bind("ipc:///tmp/workers");
// Launch pool of worker processes
for (int i = 0; i < 5; ++i) {
if (fork() == 0) {
// worker process runs here
worker_routine(NULL);
return 0;
}
}
// Connect work processes to client process via a queue
zmq::proxy (clients, workers, NULL);
return 0;
}处理每个请求的进程
现在来谈谈你的需求,每个请求一个进程。最后一个示例代码只是为了说明zmq::proxy的用法,它是为了通过路由器-经销商模式简化服务器代码而提供的。但是它不能满足你的需求。因此,您必须手动实现它。它看起来就像another example。不同之处在于,当前端套接字可读时,您需要调用fork(),并将while循环放入子进程。
if (items[0].revents & ZMQ_POLLIN) {
if (fork() == 0) {
// sub process runs here
while (1) {
// forward frames here
}
// sub process ends here
return 0;
}
}建议
最后,我不得不说,除非您的场景真的很特殊,否则为一个请求创建一个流程太繁重了。请使用线程,或者考虑像zmq::poll这样的异步IO。
https://stackoverflow.com/questions/16114948
复制相似问题