我正在尝试使用内置的共享内存函数在PHP中实现一个简单的非阻塞信号量。我的脚本基本上是这样的:
$key = ftok(__FILE__, 'A');
$shmId = shm_attach($key);
$runningKey = 37238383940234;
// die now if the script is already running
if (shm_has_var($shmId, $runningKey)) {
echo "Another instance is running\n";
exit;
}
// tell other instances that I'm running so that they die
shm_put_var($shmId, $runningKey, true);
sleep(20);
// drop shared memory key
shm_remove_var($shmId, $runningKey);
// terminate script
exit;
只要脚本正常启动和结束,这就很有效。但是,假设脚本在运行时意外死亡(在shm_put_var()之后,但在shm_remove_var()之前)。例如,进程被control-C杀死或发送SIGTERM。我的测试表明,当重新启动脚本时,共享内存变量会保留now-dead实例设置的值。我可以理解为什么会这样。但是,我正在寻找一种解决方法,或者对替代方法提出一些建议。
我的目标是一个非阻塞信号量,它将使同一个CLI脚本的多个实例彼此堆积在一起,同时考虑脚本设置信号量并在它有机会之前死亡的情况清除它。
非常感谢!
答案 0 :(得分:2)
由于你正在处理进程之间的锁(相反,比方说,在同一进程上运行的PHP请求),为什么不在一个虚拟文件上使用flock()(其路径将充当信号量)键)?如果进程因任何原因而死,操作系统会自动释放锁。