php多用户读写文件冲突问题解决措施
发布时间:2022-07-05 16:41:28 所属栏目:PHP教程 来源:互联网
导读:其实解决多调用同时写一个文件时我们会使用flock来解决些问题,这样同一时间只有一个用户可以写文件,同时其它用户进行等待队列了,下面我来介绍一下flock解决多用户读写文件冲空问题. 所以一般的方案会是,代码如下: $fp = fopen(/tmp/lock.txt, w+); if (flock
其实解决多调用同时写一个文件时我们会使用flock来解决些问题,这样同一时间只有一个用户可以写文件,同时其它用户进行等待队列了,下面我来介绍一下flock解决多用户读写文件冲空问题. 所以一般的方案会是,代码如下: $fp = fopen("/tmp/lock.txt", "w+"); if (flock($fp, LOCK_EX)) { fwrite($fp, "Write something heren"); flock($fp, LOCK_UN); } else { echo "Couldn't lock the file !"; } fclose($fp); 但在PHP中,flock似乎工作的不是那么好,在多并发情况下,似乎是经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉,好像在很多linux/unix系统中,都会有这样的情况发生. 所以使用flock之前,一定要慎重考虑. } fclose($fp); } 超时设置为1ms,如果这里时间内没有获得锁,就反复获得,直接获得到对文件操作权为止,当然,如果超时限制已到,就必需马上退出,让出锁让其它进程来进行操作. 方案二:不使用flock函数,借用临时文件来解决读写冲突的问题. 大致原理如下: 1。将需要更新的文件考虑一份到我们的临时文件目录,将文件最后修改时间保存到一个变量,并为这个临时文件取一个随机的,不容易重复的文件名。 2。当对这个临时文件进行更新后,再检测原文件的最后更新时间和先前所保存的时间是否一致。 3。如果最后一次修改时间一致,就将所修改的临时文件重命名到原文件,为了确保文件状态同步更新,所以需要清除一下文件状态。 4。但是,如果最后一次修改时间和先前所保存的一致,这说明在这期间,原文件已经被修改过,这时,需要把临时文件删除,然后返回false,说明文件这时有其它进程在进行操作。 大致实现代码如下: $dir_fileopen = "tmp"; function randomid() { return time().substr(md5(microtime()), 0, rand(5, 12)); $newfile = true; } $fp = fopen($tempfilename, $mode); return $fp ? array($fp, $filename, $id, @filemtime($filename)) : false; } function cfwrite($fp,$string) { return fwrite($fp[0], $string); } function cfclose($fp, $debug = "off") { global $dir_fileopen; $success = fclose($fp[0]); clearstatcache(); $tempfilename = $dir_fileopen."/".$fp[2].md5($fp[1]); if ((@filemtime($fp[1]) == $fp[3]) || ($fp[4]==true && !file_exists($fp[1])) || $fp[5]==true) { rename($tempfilename, $fp[1]); }else{//开源代码phpfensi.com unlink($tempfilename); //说明有其它进程 在操作目标文件,当前进程被拒绝 $success = false; } return $success; } $fp = cfopen('lock.txt','a+'); cfwrite($fp,"welcome to beijing.n"); fclose($fp,'on'); 对于上面的代码所使用的函数,需要说明一下: 1.rename();重命名一个文件或一个目录,该函数其实更像linux里的mv,更新文件或者目录的路径或名字很方便. 但当我在window测试上面代码时,如果新文件名已经存在,会给出一个notice,说当前文件已经存在,但在linux下工作的很好. 2.clearstatcache();清除文件的状态.php将缓存所有文件属性信息,以提供更高的性能,但有时,多进程在对文件进行删除或者更新操作时,php没来得及更新缓存里的文件属性,容易导致访问到最后更新时间不是真实的数据,所以这里需要使用该函数对已保存的缓存进行清除. (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |