具有单个编写器,多个读取器的Linux IPC

问题描述 投票:0回答:1

在我的应用程序中,我有一个从外部硬件进行的过程((写程序))读取数据。此过程应向几个“阅读器”提供一致的数据包

问题:一个进程如何在多个客户端看到个人FIFO结束之时向多个客户端发送一致的数据包(而不阻塞)?我在Debian Linux上。

1]在我的第一种方法中,我尝试了“ 数据报-Unix域套接字”,该方法效果很好。但是使用“ writer”作为服务器,所有客户端都必须永久轮询服务器。 :-(他们几次得到一包。如果轮询速度不够快,则会错过数据包。

2)我的第二种方法是FIFOsNamed Pipes],它也可以工作,但是对于一些读者来说,“奇怪的事情发生了”,我在这里得到了确认:http://beej.us/guide/bgipc/output/html/multipage/fifos.html

我尝试过这一点,整天都在搜索网络和stackoverflow,但是我找不到合理的答案。

编辑:抱歉,我没有提到:我不能使用socketpair()fork。我的程序是独立开发的。我想在开发新读者的同时准备好[[writer。

linux sockets client-server ipc datagram
1个回答
1
投票
如果编写器进程是服务器,则它可能会fork客户端处理,而仅仅是pipe(2)即可进行通信。如果没有父/子关系,请考虑使用[[双向([[)或mkfifo(3)AF_UNIX ....]制成的

命名管道。 C0]套接字比同一台计算机上的TCP / IP或UDP / IP快得多。

请注意,您的writer进程正在从您的硬件设备读取数据,并且正在将数据写入或发送到多个

reader

客户端。因此,您的编写器进程同时处理many文件描述符(要读取的硬件设备以及要写入客户端的套接字或管道,每个客户端至少一个文件描述符)。]]但是,重要的是具有某些unix(7)(特别是在服务器端,也可能在客户端内部)。这意味着您在循环中调用了诸如scoket(2)之类的

multiplexing syscall,并且您“决定”是要读取,写入还是连接(以及应该读取,应该写入或应该连接哪个文件描述符) )。另请参见AF_UNIXevent looppoll(2)read(2)write(2)等。请注意,您应该使用事件循环缓冲数据(因为connect(2)send(2)可以位于“部分”或“不完整”消息)。

注意,在等待I / O时recv(2)没有占用CPU资源。您可以但不应该再使用一些较旧的多路复用syscall(例如已过时的read ...)。

使用write

您可能想使用库来提供事件循环,例如pollselect(2) ...另请参见poll(2)。该事件循环也应该(在服务器端)轮询然后读取硬件设备。[如果某些程序使用的是Qt或Gtk之类的GUI工具箱(例如,在客户端),则应该从该工具箱提供的现有事件循环中受益...

您应该

阅读libevent

并了解libev

如果信号或计时器很重要(请仔细阅读[this answerAdvanced Linux Programming]),Linux特定的C10K problemsignal(7)可能会非常有用,因为它们可以很好地与事件循环配合使用。这些特定于Linux的系统调用(time(7)signalfd(2) ...)太新了,无法在高级Linux编程

中提及。

顺便说一句,您可以研究与您类似的现有自由软件的源代码,和/或使用timerfd_create(2)了解他们正在执行的确切syscall。如果您在多路复用系统调用周围没有循环(àla signalfd),那么您就没有事件循环,并且您的[[设计有错误,无法可靠地工作] >>(因为您需要对几个]做出反应>文件描述符

一次

)。

您也可以使用多线程方法,但是它要复杂得多,在您的特定情况下不值得付出努力。

© www.soinside.com 2019 - 2024. All rights reserved.