PHP是多线程的,有时候需要保持数据的唯一性和完整性,不得不使用同步功能,但是PHP却没有提供类似Windows API的互斥功能(例如:EnterCriticalSection,LeaveCriticalSection),
但是PHP有文件锁定功能,利用这个功能来实现互斥是可以的。
先看PHP提供的文件锁定函数:
flock() 函数锁定或释放文件。
若成功,则返回 true。若失败,则返回 false。
函数原型:flock(file,lock,block)
参数 描述
file 必需。规定要锁定或释放的已打开的文件。
lock 必需。规定要使用哪种锁定类型。
block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。
特别说明 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)。
下面的代码是对a.txt文件进行读取的时候,采取锁定功能:
$strLockFilePath='./a.txt';
$fLockFileHand=fopen($strLockFilePath,"rb");
if ($fLockFileHand){
// 这个是锁定文件函数,,这个相当于 WinAPI 的 EnterCriticalSection 函数
if(flock($fLockFileHand,LOCK_EX | LOCK_NB)){
// 锁定成功
// 在这里开始写你的正文代码
// 最后,记得释放这个锁定句柄,不然的话其他线程就不能进入了,这个相当于 WinAPI 的 LeaveCriticalSection 函数
flock($fLockFileHand,LOCK_UN);
}
// 最后,释放文件句柄。
fclose($fLockFileHand);
}
有个技巧,就是锁定文件不要全都用同一个文件,最好不相关的任务锁定不同的文件,这样运行效率才高。例如:一个在线销售商城有两个任务,一个是更新商品库存信息的,一个是访客注册的,这个时候没必要两个都使用同一个文件(a.txt)进行锁定,毕竟这两个任务没有交集,没有相关性,为了提高效率,一个锁定a.txt,另一个锁定b.txt就行了。
可以写一段自动创建用于互锁文件的函数,这是我的代码:
可以参考下。