![为什么 Debian 的 PHP sessionclean 脚本首先触及所有打开的文件?](https://linux22.com/image/733895/%E4%B8%BA%E4%BB%80%E4%B9%88%20Debian%20%E7%9A%84%20PHP%20sessionclean%20%E8%84%9A%E6%9C%AC%E9%A6%96%E5%85%88%E8%A7%A6%E5%8F%8A%E6%89%80%E6%9C%89%E6%89%93%E5%BC%80%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我目前正在学习/usr/lib/php/sessionclean
。有一件事我不太明白。在清理之前触摸所有打开的会话文件的目的是什么?我理解这可以防止删除当前打开但尚未写入的过期会话。但这仍然是一种竞争条件吗?如果 PHP 进程在 touch 和 delete 命令之间打开过期的会话文件会怎样?
答案1
当命令评估会话文件时,超过最大生存期的会话文件find
将被删除。
文件最迟在 PHP 脚本执行完毕后才会更新。但是,在执行期间因为会话处于空闲状态而终止会话可能并不公平。因此,更新touch
当前正在执行 php 进程的会话文件的修改时间。
是的,存在竞争条件,即 php 进程在 之后启动touch
,恢复太旧的会话,并因为在 执行垃圾收集之前未完成而被删除find
。该会话已经存在了整个生命周期,可能持续了几分钟。在几分之一秒的窗口中错过扩展并不是什么大问题。
另一种方法是 PHP 的内置实现,在执行时有 1% 左右的几率运行垃圾收集。对于访问量较小的网站,它可能无法可靠地触发。
另外,外部脚本允许锁定会话目录的安全性,这就是 Debian 维护者这样做的原因。