加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

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没来得及更新缓存里的文件属性,容易导致访问到最后更新时间不是真实的数据,所以这里需要使用该函数对已保存的缓存进行清除.
 
 
 
 

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读