【发布时间】:2016-08-17 13:17:41
【问题描述】:
在一个多线程程序(在 ARM 上运行)我有
一个主线程,除其他外,它定期检查 popen( "pidof -s prog" ) 是否有另一个程序正在运行。我对文件描述符使用O_CLOEXEC 标志并检查fgetc() 是否从管道接收到任何内容。 将文件描述符设置为“非阻塞”不会导致读取任何内容,也无济于事。来自 shell 命令的相同 pidof 命令运行良好。
在另一个线程中,子进程中带有立即execl() 的fork() 用于在发生特定事件时启动rsync 操作。父母使用信号处理程序来观察孩子的状态,并可以选择在另一个特定事件中杀死孩子。不管我是用rsync 还是sleep 调用exec(),结果都是一样的。
问题是主线程中的fgetc()一直阻塞,直到子进程终止。
我将尝试通过fork()ing 及早解决这个问题(在应用程序是单线程的某个时候,正如我开始的another post 所假设的那样)。
但无论如何:
我想了解从管道读取时导致fgetc() 阻塞的原因。
到目前为止我尝试过的一些事情:
- 我尝试使用一个小型示例应用程序来重现该问题,该应用程序执行上述操作,并希望它会显示相同的错误行为,但不幸它工作正常,这就是我这样做的原因此处暂不提供任何代码。也许我错过了相关点。
- 通过
system()使用相同的rsync调用不会导致任何问题 -
我查看了
system()implementation,可以看到信号在fork()ing 之前被操纵:- SIGCHLD 被阻止
- SIGINT 和 SIGQUIT 被忽略
我需要 SIGCHLD 的信号处理程序,但出于好奇,我尝试在上面的代码中执行相同的操作(我将
sigprocmask()替换为pthread_sigmask()) - 没有任何成功,行为保持不变。我在 BSP 提供的源代码中找不到
system()的任何实现。
程序通过fstream打开其他文件-并且没有O_CLOEXEC(会有点cumbersome to change that)
【问题讨论】:
-
system与内核源代码无关。它在你的 libc 中。 -
没错,我已经改了
-
您的问题是什么?假设它是“从管道读取时导致
fgetc()阻塞的原因”,您的编辑现在解决了吗?如果是这样,最好将其移出答案并将其标记为已接受。 -
我已经发布了编辑,所以人们现在不要再浪费时间来回答这个问题了。它似乎已修复,但我想在将其发布为答案之前进行一些测试以确保。
标签: c++ linux multithreading