在我的应用程序中,我有一个从外部硬件进行的过程((写程序))读取数据。此过程应向几个“阅读器”提供一致的数据包。
问题:一个进程如何在多个客户端看到个人FIFO结束之时向多个客户端发送一致的数据包(而不阻塞)?我在Debian Linux上。
1]在我的第一种方法中,我尝试了“ 数据报-Unix域套接字”,该方法效果很好。但是使用“ writer”作为服务器,所有客户端都必须永久轮询服务器。 :-(他们几次得到一包。如果轮询速度不够快,则会错过数据包。
2)我的第二种方法是FIFOs(Named Pipes],它也可以工作,但是对于一些读者来说,“奇怪的事情发生了”,我在这里得到了确认:http://beej.us/guide/bgipc/output/html/multipage/fifos.html
我尝试过这一点,整天都在搜索网络和stackoverflow,但是我找不到合理的答案。
编辑:抱歉,我没有提到:我不能使用socketpair()
和fork
。我的程序是独立开发的。我想在开发新读者的同时准备好[[writer。
fork
客户端处理,而仅仅是pipe(2)即可进行通信。如果没有父/子关系,请考虑使用[[双向([[)或mkfifo(3)和AF_UNIX
....]制成的命名管道。 C0]套接字比同一台计算机上的TCP / IP或UDP / IP快得多。
请注意,您的writer进程正在从您的硬件设备读取数据,并且正在将数据写入或发送到多个reader
客户端。因此,您的编写器进程同时处理many文件描述符(要读取的硬件设备以及要写入客户端的套接字或管道,每个客户端至少一个文件描述符)。]]但是,重要的是具有某些unix(7)(特别是在服务器端,也可能在客户端内部)。这意味着您在循环中调用了诸如scoket(2)之类的multiplexing syscall,并且您“决定”是要读取,写入还是连接(以及应该读取,应该写入或应该连接哪个文件描述符) )。另请参见AF_UNIX
,event loop,poll(2),read(2),write(2)等。请注意,您应该使用事件循环缓冲数据(因为connect(2)和send(2)可以位于“部分”或“不完整”消息)。
read
...)。 使用write
poll
或select(2) ...另请参见poll(2)。该事件循环也应该(在服务器端)轮询然后读取硬件设备。[如果某些程序使用的是Qt或Gtk之类的GUI工具箱(例如,在客户端),则应该从该工具箱提供的现有事件循环中受益...您应该
阅读libevent
并了解libev。如果信号或计时器很重要(请仔细阅读[this answer和Advanced Linux Programming]),Linux特定的C10K problem和signal(7)可能会非常有用,因为它们可以很好地与事件循环配合使用。这些特定于Linux的系统调用(time(7)和signalfd(2) ...)太新了,无法在高级Linux编程
中提及。顺便说一句,您可以研究与您类似的现有自由软件的源代码,和/或使用timerfd_create(2)了解他们正在执行的确切syscall。如果您在多路复用系统调用周围没有循环(àla 一次signalfd
),那么您就没有事件循环,并且您的[[设计有错误,无法可靠地工作] >>(因为您需要对几个]做出反应>文件描述符
您也可以使用多线程方法,但是它要复杂得多,在您的特定情况下不值得付出努力。