PHP通过文件锁防止进程重复并发
这个场景是之前定时任务每分钟执行一次crontab定时任务,请求第三方接口.
但是有时候第三方接口不太稳定,执行时间可能会超过一分钟.
所以我们使用简单的文件锁,每次请求的时候锁一下某个文件.
下一个分支再执行的时候,发现文件被锁就不在执行该任务了.
- flock操作类型
(1)LOCK_SH 共享锁,多个进程可以使用同一把锁,常被用作读共享锁;
(2)LOCK_EX 排他锁,同时只允许一个进程使用,常被用作写锁;
(3)LOCK_UN 释放锁;
(4)LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
- fopen 的model参数
'r' 只读方式打开,将文件指针指向文件头。
'r+' 读写方式打开,将文件指针指向文件头。
'w' 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
'w+' 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。
'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
'x' 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的 open(2) 系统调用指定 O_EXCL|O_CREAT 标记是等价的。
'x+' 创建并以读写方式打开,其他的行为和 'x' 一样。
'c' 只需要打开文件。如果文件不存在,则创建该文件。如果它存在,它既不是截断的(与“w”相反),也不是对这个函数的调用失败(就像“x”一样)。文件指针位于文件的开头。如果希望得到一个咨询锁(请参阅flock()),在尝试修改该文件之前,这可能是有用的,因为使用“w”可以在获得锁之前截断文件(如果需要截断,则在请求锁定后可以使用ftruncate())。
'c+' 打开文件阅读和写作;否则,它的行为与“c”相同。
- PHP案例
$folder = '/tmp';
$lock = $folder . "/send_price.lock";
$fp = fopen($lock, 'c');
if(!flock($fp, LOCK_EX | LOCK_NB)){
exit('其他进程正在运行中');
}