2011-01-19 166 views
0

我有一种情况,我有一个复杂消息的传入流,它们在以简化格式传递给实际处理程序之前需要进行一些处理。控制文件描述符的准备

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

我想知道是否有一种配置FIFO的方式,以便我可以手动定义文件描述符何时准备就绪,即生产者已成功编写完整软件包时,我想要有一个向读取结束(通过文件描述符)发送信号的方式是读取已准备就绪。有没有一种方法可以通过ioctl()来实现,或者除了提供这种行为的FIFO之外还有一些抽象(在Linux世界中)? (我知道pthread和条件变量,但我想生产者和消费者之间的耦合被限制到共享文件描述。)

回答

1

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

没有这种方法。

你必须。

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

另一种方法是总是发送一个固定长度的消息,所以你总是知道多少阅读拿到1个消息,或者使用AF_UNIX数据报套接字 - 只要你可以定义一个合理的最大尺寸信息。

2

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

套接字对可以在域AF_UNIX进行与SOCK_STREAM类型(基于流的,您的使用将需要帧化/重新装配),SOCK_DGRAM(数据报为基础,将不被分段或合并的),或SOCK_SEQPACKET(基于记录,可能被分割但不合并)。