0

我有一个案例,我有一个复杂消息的传入流,在将它们以简化格式传递给实际处理程序之前需要进行一些处理。

我想使用一个FIFO文件描述符,一个线程从一端填充它,另一个线程从另一端读取。现在我想要的那种行为:读取线程正在等待select(),并且我想保证在唤醒时,有一个可以通过调用读取的完整包read(),即我想避免重新组装由于缓冲区大小导致的碎片(包保证低于内核到用户空间缓冲区传递限制)。

我想知道是否有一种方法可以配置 FIFO,以便我可以手动定义文件描述符何时准备好,即当生产者成功编写完整包时,我想有一种方法可以向读取准备就绪的读取端(通过文件描述符)。有没有办法通过ioctl()或者除了提供这种行为的FIFO之外还有一些抽象(在Linux世界中)?(我知道pthread和条件变量,但我希望生产者和消费者之间的耦合仅限于共享文件描述符。)

4

2 回答 2

2

尝试socketpair()而不是pipe() / mknod(S_IFIFO)

可以在域中创建一个套接字对AF_UNIX,类型为SOCK_STREAM(基于流,您的使用将需要成帧/重组),SOCK_DGRAM(基于数据报,不会分段或合并),或SOCK_SEQPACKET(基于记录,可能分段但不合并) .

于 2011-01-19T19:12:57.147 回答
1

我想知道是否有一种方法可以配置 FIFO,以便我可以手动定义文件描述符何时准备就绪

没有这样的方法。

你必须。

  • 定义某种消息框架。例如,将消息长度添加到消息中,或者用换行符分隔它们(假设消息中不能出现换行符)。在换行符分隔消息的情况下,您可以将文件描述符包装在 FILE* 和 fgets() 中,除非您依赖 select() 来多路复用多个流或提供超时。
  • 准备好处理read()或类似读取 1 条消息、少于 1 条消息或多于 1 条消息 - fifo 只是一个字节流,因此该层上没有消息边界。
  • 根据您决定如何将它们分开来解析您已阅读的消息。

另一种选择是始终发送固定长度的消息,以便您始终知道要读取多少才能获得 1 条消息,或者可能使用 AF_UNIX 数据报套接字 - 只要您可以定义合理的最大消息大小。

于 2011-01-19T19:09:02.780 回答