【问题标题】:sharing sockets between processes on linux在 Linux 上的进程之间共享套接字
【发布时间】:2012-06-26 14:01:09
【问题描述】:

我有多个守护进程(一个网关和多个服务,都在同一个节点上运行),其中一些服务守护进程需要“软实时”响应网络上到达的请求,我的拱门就像我有一个网关守护进程,它根据一些协议标签将传入的数据包路由到相应的服务守护进程。服务守护进程处理请求并将响应发送回连接到网络的 gw 守护进程。一切正常,但我没有达到“软实时”并看到滞后。

我计划以下面的方式即兴创作,在网关和服务守护进程之间共享网络连接,我将有一个通知方案,当数据包到达连接时,gw 守护进程不会使数据包出队从套接字队列查看协议头并“通知”相应的服务守护进程“数据已到达”,在接收到通知时,服务守护进程获取一个二进制信号量并将数据从套接字队列中取出。将有 2 个这样的信号量,一个用于写入,另一个用于读取。当服务守护进程需要发送数据时,它会抓取写入信号量并发送数据。当它从网关守护程序接收到“数据到达”通知时,它会抓取读取信号量并将数据从套接字中取出。在每个新的连接请求上,网关守护程序将使用“sendmsg”将连接发送到服务守护程序。

有没有人尝试过这个方案?你觉得这种方法有什么问题吗?请评论/建议。

【问题讨论】:

  • 您是否确定网关和服务守护程序之间的复制开销导致了您的问题?如果您没有,您认为这会有所帮助的原因是什么?
  • 您当前使用的是什么 IPC,是否需要按照严格的 FIFO 顺序进出网关连接?
  • #Provost ,整个想法是在数据从 gw 守护程序传输到服务守护程序时避免用户空间和内核空间之间的数据复制。我相信这是一个重要的开销,不用说许多文章都谈到了它,并且许多程序试图避免这种情况。仍然要回答你的问题,我还没找到。
  • #Duck,对于通知通道,我计划使用常规管道或 fifos。为了发送打开的套接字,我将使用 sendmsg,每个数据包都有一个“协议”标签,用于标识消费者服务守护进程。

标签: linux sockets network-programming


【解决方案1】:

如果您想避免复制开销,您可能应该使用splice,而不是尝试在多个守护程序之间共享套接字。该解决方案将非常难以调试和维护。

我希望(并希望)您的网络协议有一个标头,可以让网关轻松知道将数据包路由到哪里,然后是一个以服务守护进程为目标的有效负载。

在伪代码中,网关会这样做:

while (data on socket)
{
    header = read(socket, sizeof(header));

    service_socket = find_service(header);
    splice(socket, NULL, service_socket, NULL, header->payload_length, 0);
}

【讨论】:

  • splice 对 in 和 out fds 的性质有一些限制,其中之一应该是管道(输入或输出)。特别是在这种情况下服务 fd 不能是套接字,它必须是带来消息边界问题的管道,经过大量研究后,我决定使用消息队列在网关和服务守护程序之间进行通知和套接字共享,gw 守护程序将通知服务守护进程关于消息队列通道上的新数据,在收到消息队列通知后,服务守护进程将获取读取信号量并将数据出列。这种方法还是有问题的。
  • 作弊。按照stackoverflow.com/questions/2677262/… 的建议去做。拼接到管道,然后从管道拼接到另一个插座。传递那些 fd 会让人头疼。
  • 感谢您的链接,会看到并回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-18
  • 2017-01-19
  • 2017-06-14
  • 2014-01-15
  • 2016-08-08
  • 2012-08-08
  • 1970-01-01
相关资源
最近更新 更多