我的程序有这个奇怪的问题:
它尝试通过管道读取某些命令的输出来查找设备:
FILE* fp = NULL;
fp = popen ("cd /sys/bus/usb/devices; grep -i NDI */product", "r");
然后使用fgets()读取文件流并使用pclose()关闭管道。
在单线程程序中它运行良好。但是,当我把它集成到一个多线程程序中后,fgets()函数开始随机阻塞线程。
检查后,我发现fgets()阻塞,因为有时fp作为空文件流返回。在我将fp的状态设置为非阻塞并使用read()通过其 ID 读取文件后,我可以看到read()由于文件流为空而返回 -1,然后pclose()挂起。所有这些都是随机发生的。
所以我认为在这种情况下,通过 popen() 执行的命令会挂起并且永远不会终止。但为什么它随机发生?多线程程序只有另一个线程用于用户界面交互。我认为这很好,因为管道仅在本地使用。
任何想法表示赞赏。谢谢!
更新
strace 显示有时子进程在一堆 munmap() 调用之后调用 futex() 然后挂在那里: futex(0xb72eaf00, FUTEX_WAIT_PRIVATE, 2, NULL
在正常情况下,不会调用 futex。
作为参考,主进程中 strace 的输出:
1344962944.530384 pipe2([26, 27], O_CLOEXEC) = 0
1344962944.530441 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb41a8a68) = 25529
1344962944.534683 close(27) = 0
1344962944.534801 fcntl64(26, F_SETFD, 0) = 0
1344962944.534852 write(1, "entering fgets\n", 15) = 15
1344962944.534924 fstat64(26, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
1344962944.534992 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb377d000
1344962944.535065 read(26,
子进程 shell 的 strace 输出:
1344962944.534652 set_robust_list(0xb41a8a70, 0xc) = 0
1344962944.534790 getpid() = 25529
1344962944.534843 getppid() = 25453
1344962944.534917 close(12) = 0
1344962944.534983 munmap(0xa8fff000, 1048576) = 0
...
1344962944.535925 munmap(0xb2728000, 118784) = 0
1344962944.535952 close(11) = 0
1344962944.535980 close(10) = 0
1344962944.536018 futex(0xb72eaf00, FUTEX_WAIT_PRIVATE, 2, NULL