【问题标题】:Co-ordinating the accept for a shared listenning socket between multiple processes协调多个进程之间共享侦听套接字的接受
【发布时间】:2012-08-08 01:18:46
【问题描述】:

在多个进程之间协调监听套接字的接受的最佳方式是什么?

我正在考虑以下两种方法之一:

  • 有一个“主”进程,当轮到每个进程开始接受连接时,它会向每个进程发送一条消息。

    所以顺序是:

    Master 进程将令牌交给 Worker A。Worker A 接受连接,将令牌返回给 Master 进程。主进程给 Worker B 等令牌。

  • 每个进程都有一个接受线程,该线程将围绕一个共享互斥体旋转。锁定互斥体,接受连接,释放锁。

有更好的想法吗?

  • 当连接进入时,所有进程都会被唤醒。在接受连接之前,他们尝试锁定共享互斥锁。锁定互斥体的人首先接受连接。

【问题讨论】:

  • 如果我是你,我会采用大师级方法。
  • 感谢您的建议。我目前已经实现了这个(主进程发送消息作为令牌),但我认为它太慢了。对于每个接受,我都会进行以下“额外”系统调用。 Worker 调用“send()”发送回令牌。主睡眠是“select()”调用“recv()”获取token。然后调用“send()”将令牌发送给 Worker B 并在“select()”中返回睡眠。工人 B 调用“recv()”来接受令牌。所以我想也许它太慢了......

标签: c sockets


【解决方案1】:

我也认为主解决方案是不错的选择:

/* Process struct */
typedef struct _process_t {
    unsigned long process_id;
    struct _process_t *next;   /* next process */
    struct _process_t *prev;   /* previous process */
    struct _process_master *master_process;  /* Master process */
    int (*accepting_socket) (struct _process_t *); /* process accepet function */
    char *received_data_buffer;      /* the data received over the socket */
} process_t;

/* List of process */
typedef struct _process_list {
    process_t *head;
    process_t *tail;
    int count;
} process_list;

/* The master process */
typedef struct _process_master {
    process_list socket_listners;   /* All the process listening */
    process_list ready_listners;    /* Process ready to listen and receive*/

    ..... /* Complete this struct */
} process_master;

如果您发现带有进程的解决方案很慢,您可以改用threads(它们共享相同的内存),但是代码可能会增加复杂性并且很难跟踪错误。

第二个解决方案并不比第一个快,因为获取互斥体的成本和所有进程之间的上下文切换。

【讨论】:

  • 谢谢!关于互斥量获取和上下文切换;好吧,即使在 Master - Worker 场景中也会发生上下文切换。我只是在想,也许获取互斥锁可能比主 - 工作者场景中所需的所有系统调用更快。感谢您的建议!
【解决方案2】:

1) 我不确定您为什么不想要多个“线程”而不是“进程”。

但如果您需要一个工作进程池(相对于“工作线程”),那么我建议:

2) 主进程绑定、监听……并接受所有传入的连接

3) 使用“Unix 套接字”将接受的连接从主进程传递到工作进程。

4) 就“同步”而言 - 很简单。 worker 只是阻止读取 Unix 套接字,直到有一个新的文件描述符可供它开始使用。

5)您可以为工作人员设置一个共享内存块,以将“忙/闲”状态传达给主设备。

这里是关于使用“Unix 域套接字”的讨论:

史蒂文斯的“网络编程”也是一个极好的资源:

【讨论】:

  • 谢谢!我宁愿为工人使用进程而不是线程。从一个进程向另一个进程发送套接字的想法听起来很有趣。 IE。让一个进程完成所有接受并将其发送到工作进程以进行进一步处理。会试一试的!谢谢。
【解决方案3】:

只是我最终使用的更新 (3):当连接进入时,所有进程都会被唤醒。在接受连接之前,他们尝试锁定共享互斥锁。锁定互斥体的人首先接受连接。

这比来回传递令牌要快得多。

谢谢大家!

【讨论】:

    猜你喜欢
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    相关资源
    最近更新 更多