如何停止 fgets 从 FIFO 文件中读取

Posted

技术标签:

【中文标题】如何停止 fgets 从 FIFO 文件中读取【英文标题】:How to stop fgets reading from FIFO file 【发布时间】:2016-01-11 04:22:27 【问题描述】:

我有两个进程,第一个是从标准输入读取并写入 FIFO 文件,第二个是等待来自 FIFO 文件的消息。

我正在使用这个程序结构:

while(run)

  fgets(string, sizeof(string), fp);

当哨兵(运行)更改为 0 以停止进程时,它并没有真正停止,因为它卡在了fgets() 函数中。 我该如何解决?

我希望程序在哨兵变为0时等待消息然后立即停止程序。

【问题讨论】:

执行此操作的常用方法是使用select 等待输入,然后再调用fgets。要及早爆发,请清除run,然后向进程发送信号。信号会中断select,它会回到循环的顶部,看到run已经被清除并因此退出。 你能告诉它在这个特殊情况下的样子吗?? 另一种选择是使用信号处理程序来清除run。如果在没有SA_RESTART 标志的情况下安装处理程序,它的传递将中断同一线程中的任何阻塞读/写系统调用。不过,就个人而言,我会使用低级 (unistd.h) I/O、非阻塞和 select()。 什么会导致run 发生变化? 你在run的声明中添加了volatile吗? 【参考方案1】:

我认为您的 fifo 是在 阻塞模式 下打开的,因此在 fgets() 中,如果数据不可用,则该调用将被阻塞,直到 fifo 有一些新数据。

所以通过在 open call 中使用 O_NONBLOCK 来避免在非阻塞模式下打开 FIFO。

在这里阅读更多。 http://www.tldp.org/LDP/lpg/node19.html

这样,如果没有可用的数据,fgets 会返回错误而不是卡住该调用。在下一个 while 循环检查中,run 将是 0,因此它会从这个循环中出来。

【讨论】:

打开 fifo 我使用 fopen() 函数。我可以在 fopen 中设置这样的东西吗?? 看这个***.com/questions/580013/… 使用open() 打开fifo 然后使用fdopen() 将文件描述符转换为文件指针,然后执行所有文件操作 我在使用 fdopen 时遇到了这个问题:分段错误(核心转储) 你可能做错了什么。发布一个新问题,其中包含一些代码的详细信息。以便其他人可以帮助您

以上是关于如何停止 fgets 从 FIFO 文件中读取的主要内容,如果未能解决你的问题,请参考以下文章

fgets与fputs

fgets 无法在 Ubuntu 20.04 上从管道读取两次

c语言中gets ,getschar 和fgets 的用法及三者之间的差别

为啥 alarm() 导致 fgets() 停止等待?

在 FIFO 到达时从 FIFO 中读取数据(linux)

使用 fgets 从文件中读取