控制文件描述符的准备情况

时间:2011-01-19 19:02:21

标签: linux select io named-pipes fifo

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

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

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

2 个答案:

答案 0 :(得分:2)

尝试使用socketpair()代替pipe() / mknod(S_IFIFO)

套接字对可以在域AF_UNIX中创建,类型为SOCK_STREAM(基于流,您的使用将需要框架/重组),SOCK_DGRAM(基于数据报,不会是碎片或合并),或SOCK_SEQPACKET(基于记录,可能是碎片但未合并)。

答案 1 :(得分:1)

  

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

没有这样的方式。

你必须。

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

另一种方法是始终发送一个固定长度的消息,这样你就可以随时知道要读取多少消息,或者使用AF_UNIX数据报套接字 - 只要你能定义一个合理的消息最大大小。 / p>