我正在使用 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>