【问题标题】:read the last line of a fifo读取 fifo 的最后一行
【发布时间】:2010-02-21 15:05:27
【问题描述】:

情况如下:某些进程将行写入 fifo 文件(使用 mkfifo 创建)。在我的程序中的某个时刻,我想读取 fifo 中的最后一行,并丢弃所有其他行。仅当 fifo 中的行少于一行时,该过程可能会阻塞。

我想不出一个干净的方法来做到这一点,有什么想法吗?

编辑:写入过程永远不会停止将行写入fifo,我的意思是最后一行是我读取fifo时的最后一行。它后面不一定跟着 EOF。

【问题讨论】:

  • “最后一行”是什么意思? pipe(又名fifo)是一个流,而不是一个文件,读取的行你不知道它是最后一个还是稍后会提供更多数据。
  • 写入过程写入管道的最后一行是最新的信息。这就是为什么当我汇集信息时,我想要最新的。

标签: c unix fifo


【解决方案1】:

如果您主要担心读取会阻塞,则将 FIFO 打开为非阻塞。我假设你知道你在流中寻找什么,并且会简单地丢弃之前的所有内容。

您还可以使用select() 之类的内容来通知管道中是否有要读取的内容。

【讨论】:

    【解决方案2】:

    如果我正确理解了您的问题,那么您有另一个进程通过 fifo 向您的程序提供数据,并且新数据会淘汰任何以前收到的数据,因此您只对可用的最新数据感兴趣。

    在这种情况下,我的方法是 - 为fifo 的描述符设置非阻塞模式,使用O_NONBLOCK 标志为fcntl() 系统调用,并使用如下内容:

    while (!exit_condition) {
        bytes = read(fd, wrkbuf, sizeof(wrkbuf));  // error handling omitted
        if (0 == bytes && bytes_to_process > 0) {
            process(wrkbuf, bytes_to_process);
            bytes_to_process = 0;
        } else
            bytes_to_process = bytes;
    }
    

    【讨论】:

      【解决方案3】:

      我能想到的唯一方法是让你的程序(读取)读取 FIFO 中的所有信息——也就是说,程序中的读取指针始终位于管道的末尾。阅读消息后,您会将其添加到消息的内部列表(即队列或类似的东西)中。您还将维护指向最后一条消息的指针。

      然后,读取最后一行并丢弃所有其他行只是跟随指向最后一条消息的指针的过程,如果需要,清除队列。

      这里的问题是您的内部队列可能会变大,并且您需要对队列和最后一条消息指针进行并发控制。我会让 FIFO 阅读器在它自己的线程中除了听管道什么都不做。当有消息进入时,您需要锁定队列,添加新消息并更新最后一条消息指针,然后释放锁定。确保在释放锁之前处理所有可用的传入消息。在进行处理的线程中,您应该锁定队列以对其进行操作。确保您锁定队列的时间不超过绝对必要,否则您将遇到性能问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多