我有这个最小的PHP 8.1的例子:
<?php
ini_set('display_errors', 'on');
if(($fp = @fopen(__DIR__ . '/test.some', 'r+')) === false){
$fp = fopen(__DIR__ . '/test.some', 'c+');
}
flock($fp, LOCK_EX);
exec('eval `ssh-agent -s`', $output1, $resultCode1);
var_dump($output1, $resultCode1);
fclose($fp);
问题是当我运行这个脚本两次时,第二个实例将阻塞flock()函数调用,可能是因为第一个实例没有释放文件锁。
当我执行()不同的命令而不是eval `ssh-agent -s`
时,例如git --version
,那么一切似乎都工作正常。
有谁知道是什么问题吗?是PHP的bug还是我对flock()的理解不到位?
通常,当一个进程退出时,所有的文件锁都会自动释放(源)。然而,ssh-agent
作为一个后台进程被分叉,这导致它从父进程继承所有的文件锁。
这个行为可以通过运行sudo fuser -v /tmp/test.some
来确认,这表明ssh-agent
继承了锁。
USER PID ACCESS COMMAND
/tmp/test.some: testuser 19834 F.... ssh-agent
testuser 19873 F.... php8.1
添加flock($fp, LOCK_UN)
,正如Pran Joseph在评论中建议的那样,确实解决了这个问题。