如何停止 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 无法在 Ubuntu 20.04 上从管道读取两次