我正在使用 popen() 创建一个管道,并且该过程正在调用第三方工具,在极少数情况下我需要终止该工具。
::popen(thirdPartyCommand.c_str(), "w");
如果我只是抛出一个异常并展开堆栈,我的展开尝试在我不再需要其结果的第三方进程上调用 pclose()。但是,pclose() 永远不会返回,因为它在 Centos 4 上使用以下堆栈跟踪阻塞:
#0 0xffffe410 in __kernel_vsyscall ()
#1 0x00807dc3 in __waitpid_nocancel () from /lib/libc.so.6
#2 0x007d0abe in _IO_proc_close@@GLIBC_2.1 () from /lib/libc.so.6
#3 0x007daf38 in _IO_new_file_close_it () from /lib/libc.so.6
#4 0x007cec6e in fclose@@GLIBC_2.1 () from /lib/libc.so.6
#5 0x007d6cfd in pclose@@GLIBC_2.1 () from /lib/libc.so.6
有什么方法可以在调用 pclose() 之前强制调用成功,这样我就可以通过编程方式避免这种情况,即我的进程挂起等待 pclose() 成功,而它永远不会成功,因为我已经停止向popen()ed 进程并希望丢弃它的工作?
在尝试关闭它之前,我是否应该以某种方式将文件结尾写入 popen()ed 文件描述符?
请注意,第三方软件正在分叉自己。在 pclose() 挂起的地方,有四个进程,其中一个已失效:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
abc 6870 0.0 0.0 8696 972 ? S 04:39 0:00 sh -c /usr/local/bin/third_party /home/arg1 /home/arg2 2>&1
abc 6871 0.0 0.0 10172 4296 ? S 04:39 0:00 /usr/local/bin/third_party /home/arg1 /home/arg2
abc 6874 99.8 0.0 10180 1604 ? R 04:39 141:44 /usr/local/bin/third_party /home/arg1 /home/arg2
abc 6875 0.0 0.0 0 0 ? Z 04:39 0:00 [third_party] <defunct>