利用PHP文件锁简单进行高并发情况的处理

本周完成抽奖插件进行代码评审时,发现没有对主要的抽奖逻辑进行高并发处理。在实际生产环境中抽奖时一定会出现高并发的情况,从而会造成奖品数量不对的情况(奖品多抽的情况)。所以以后对类似高并发情况进行,充分的考虑。

————

php文件锁进行高并发处理
两种模式:阻塞模式与非阻塞模式
阻塞模式:只要有一个进程对文件进行加锁,其他进程就会等待这个文件解锁。
非阻塞模式:如果有一个进行对文件进行加锁,其他进行会返回,不会等待解锁。

————

PHP利用flock()函数对文件进行加锁(排它锁),实现并发按序进行。
flock() 函数锁定或释放文件。若成功,则返回 true。若失败,则返回 false。

flock(file,lock,block)
file 必需。规定要锁定或释放的已打开的文件。
lock 必需。规定要使用哪种锁定类型。
block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程

说明
flock() 操作的 file 必须是一个已经打开的文件指针。

lock 参数可以是以下值之一:

要取得共享锁定(读取的程序),将 lock 设为 LOCK_SH(PHP 4.0.1 以前的版本设置为 1)。
要取得独占锁定(写入的程序),将 lock 设为 LOCK_EX(PHP 4.0.1 以前的版本中设置为 2)。
要释放锁定(无论共享或独占),将 lock 设为 LOCK_UN(PHP 4.0.1 以前的版本中设置为 3)。
如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。

————

//堵塞文件锁
$fp = fopen(“lock.txt”, “r”);
//其他进程执行到这个地方时,检测到文件已经加锁,则进行等待。等到文件解锁后按照队列顺序执行程序
if( flock($fp,LOCK_EX) ) { //加锁成功
//TODO 业务逻辑

flock($fp,LOCK_UN);
}
//关闭文件
fclose($fp);

 

————

//非堵塞锁
$fp = fopen(“lock.txt”, “r”);
//其他进程执行到这个地方时,检测到文件已经加锁,则执行TODO2逻辑2,返回业务繁忙稍后再试
if( flock($fp,LOCK_EX | LOCK_NB) ) { //加锁成功
//TODO 业务逻辑

echo ‘正常业务逻辑’
flock($fp,LOCK_UN);
} else {
echo ‘业务繁忙稍后再试’;
//TODO2 逻辑2
}
//关闭文件
fclose($fp);

本文来自投稿,不代表微擎百科立场,如若转载,请注明出处:https://www.w7.wiki/develop/2701.html

发表评论

登录后才能评论