为什么这个文件锁是用flock()获得的,而不是在调用exec()后释放的?



我有这个最小的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在评论中建议的那样,确实解决了这个问题。

最新更新