首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ZeroMQ与分支服务器中的所有子进程共享上下文

ZeroMQ与分支服务器中的所有子进程共享上下文
EN

Stack Overflow用户
提问于 2013-04-20 07:37:13
回答 1查看 3.5K关注 0票数 3

我正在用C++编写一个分支聊天服务器,每个传入的客户端都有自己的进程。服务器与客户端的交互是通过普通套接字完成的,其中ZeroMQ套接字处理消息队列和进程间通信。基本问题是,当服务器派生新的客户端时,客户端的进程有上下文的副本(这就是fork所做的,对吧?),所以当它将套接字与上下文绑定时,其他客户端都不知道套接字。长话短说:如何让每个客户端线程具有相同的上下文,以便它们可以通过ZeroMQ相互通信?

我已经研究了在进程之间共享上下文的各种方法,到目前为止,我只找到了this one。问题是1)它使用一个线程池,据我所知,只创建了5个线程;这个服务器需要支持至少256个线程,因此将至少有那么多线程,2)它使用ZeroMQ与客户端对话和后端任务;我仅限于将ZeroMQ用于后端。

我看过fork邮件列表,有一条消息说ZeroMQ ()与ZeroMQ的工作方式是正交的。这是否意味着我不能在派生的子进程之间共享上下文?如果是这样的话,我如何在多个进程之间共享上下文,同时记住至少支持256个客户端和仅将ZeroMQ用于后端的要求?

编辑:清除了线程/进程的混乱。真对不起。

EDIT2:我也喜欢在线程上派生的原因是,我习惯了让主进程接受传入的套接字连接,然后派生,将新的套接字提供给子进程。我不确定如何以线程的方式做到这一点(没有真正的实践,但也不完全超出我的能力范围)

EDIT3:所以,开始用线程重写它。我想这是唯一的办法了?

EDIT4:为了进一步说明,到服务器的传入连接可以是TCP或UDP,并且当客户端连接时,我必须处理它是哪种类型,所以我不能使用ZeroMQ套接字来侦听。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-20 11:43:32

上下文共享

在链接的示例代码中共享ZMQ上下文的原因是,服务器(main())使用inproc套接字与工作者(worker_routine())通信。Inproc套接字不能相互通信,除非它们是从相同的ZMQ创建的,即使它们位于相同的进程中。在您的情况下,我认为没有必要共享它,因为不应该使用inproc套接字。因此,您的代码可能如下所示:

代码语言:javascript
复制
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循环放入子进程。

代码语言:javascript
复制
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。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16114948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档