为何调用proc_get_status()会导致proc_close()返回-1?
关于proc_close()返回值依赖proc_get_status()调用的问题
现象说明
- 不调用
proc_get_status()函数时,proc_close()返回0 - 在
proc_close()前调用proc_get_status()函数时,proc_close()返回-1
未调用proc_get_status()的代码示例
$descriptorspec = array(1 => array("pipe", "w")); $process = proc_open('ls', $descriptorspec, $pipes); echo stream_get_contents($pipes[1]); fclose($pipes[1]); //$ret_status = proc_get_status($process)['exitcode']; //echo 'ret_status: ' . print_r($ret_status, true) . PHP_EOL; $ret_process = proc_close($process); echo 'ret_process: ' . print_r($ret_process, true) . PHP_EOL;
输出
hello_world.txt ret_process: 0
调用proc_get_status()的代码示例
$descriptorspec = array(1 => array("pipe", "w")); $process = proc_open('ls', $descriptorspec, $pipes); echo stream_get_contents($pipes[1]); fclose($pipes[1]); $ret_status = proc_get_status($process)['exitcode']; echo 'ret_status: ' . print_r($ret_status, true) . PHP_EOL; $ret_process = proc_close($process); echo 'ret_process: ' . print_r($ret_process, true) . PHP_EOL;
输出
hello_world.txt ret_status: 0 ret_process: -1
PHP版本
$ php -version PHP 7.3.31-1~deb10u1 (cli) (built: Oct 24 2021 15:18:08) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.3.31-1~deb10u1, Copyright (c) 1999-2018, by Zend Technologies
期望
proc_close()的返回值不依赖是否调用proc_get_status(),两种情况都返回0。
问题解释
这是因为proc_get_status()内部会调用系统的waitpid()函数获取子进程状态,当waitpid()成功拿到子进程的退出状态后,系统会立即回收该子进程的资源(清理僵尸进程)。后续调用proc_close()时,它会再次尝试调用waitpid()获取状态,但此时子进程的信息已经不存在,因此proc_close()返回-1表示无法获取到目标进程的状态。
本质上,子进程的退出状态只能被获取一次,proc_get_status()提前消耗了这个获取机会,导致proc_close()无法再拿到有效状态值。
内容的提问来源于stack exchange,提问作者Dmytro Dzyubak
相关产品推荐
相关产品推荐

