通过popen()执行的命令随机挂起

时间:2012-08-14 14:20:21

标签: c++ linux block popen futex

我的程序有这个奇怪的问题:

它试图通过管道读取某些命令的输出来查找设备:

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

0 个答案:

没有答案