PHP文件函数flock
<?php>flock ($handle, $operation, &$wouldblock = null);<?>
?
参数说明:
$handle //文件指针
$operation //锁类型
$operation 有几个可用值:LOCK_EX【写锁】、LOCK_SH【读锁】、LOCK_UN【释放锁】
? ? ? ? 看个例子吧
?
<?php>function fileWrite($file){$fp = fopen($file, 'a');flock($fp, LOCK_EX);//上写锁/*写数据*/fwrite($fp, "1");fwrite($fp, "2");fwrite($fp, "3\r\n");flock($fp, LOCK_UN);//释放锁fclose($fp);}fileWrite('D:/txt.txt');<?>? ? ? ? 用Jmeter做下并发测试,执行3000次请求,会发现文件里有3000行123(不考虑apache或nginx的性能瓶颈)。
?
? ? ? ? 在用Jmeter做并发测试的时候,用记事本打开这个文件,改点东西,然后点击保存,你会发现下图情况
? ? ? ? 这就是因为文件上锁了,记事本进程无法写入。
? ? ? ? 前边说了,flock函数的锁机制实际上是文件系统的锁机制,它封装了某些类型文件系统的锁机制,有些文件系统flock不支持,据PHP手册上说,FAT、NTF等这种老式文件系统和网络文件系统,flock不支持。本人没测过。
? ? ? ? PHP手册还说,flock是进程级别的,多线程的时候不起作用。可能大家就要有疑惑了,PHP又没线程的概念。那把PHP放在支持多线程的服务器上呢,大家想想看。测一测。
分析到这一步呢,会发现flock依赖宿主,对环境有要求,这就深深的伤害了代码的可移植性。怕啦!!别怕,其实伤害也没多深,flock还是能满足大部分环境的。
?
? ? ? ? 针对flock的移植性稍有些不足,大家就开始研究替代办法,我也关注了下,发现网上流传着下面这样的代码
?
<?php>function fileWrite($file,$content){$lock = $file.'.lock';while (true) {if (file_exists($lock)) {usleep(100);}else{touch($lock);//上锁file_put_contents($file, $content, FILE_APPEND);//写文件@unlink($lock);//删除锁break;}}}fileWrite('D:/txt.txt','i m a phper');<?>
? ? ? ? 你觉着这段代码有锁作用么??测测!!其实都不用测,一看就锁不住,file_exists本来就可以并行执行,当两进程同时执行到file_exists,判断所谓的锁文件不存在,结果还不是冲突着呢。
锁,实际上是将并发访问排队阻塞串行化,然后依次处理访问,上边这段代码连排队都没有,怎么能上锁呢。
? ? 这时候大家可能又会问多个进程同时执行flock,不也是并行的么?是,执行flock是并行的,这只是代表申请锁是并行的,flock内部调的是宿主文件系统,自然会把锁请求排队处理。
?