php怎么解决多进程同时写一个文件的问题?

php解决多进程同时写一个文件的方法:首先复制需要更新的文件,并更改文件名;然后检查最后更新时间和先前所保存的时间是否一致;最后将所修改的临时文件重命名到原文件。

php怎么解决多进程同时写一个文件的问题?


php解决多进程同时写一个文件的方法:

首先PHP是支持进程的而不支持多线程(这个先搞清楚了),如果是对于文件操作,其实你只需要给文件加锁就能解决,不需要其它操作,PHP的flock已经帮你搞定了。
用flock在写文件前先锁上,等写完后解锁,这样就实现了多线程同时读写一个文件避免冲突。大概就是下面这个流程

/**flock(file,lock,block)*file 必需,规定要锁定或释放的已打开的文件*lock 必需。规定要使用哪种锁定类型。*block 可选。若设置为 1 或 true,则当进行锁定时阻挡其他进程。*lock*LOCK_SH 要取得共享锁定(读取的程序)*LOCK_EX 要取得独占锁定(写入的程序)*LOCK_UN 要释放锁定(无论共享或独占)*LOCK_NB 如果不希望 flock() 在锁定时堵塞/*if (flock($file,LOCK_EX)){fwrite($file,'write more words');flock($file,LOCK_UN);}else{//处理错误逻辑}fclose($file);)

登录后复制

相关学习推荐:PHP编程从入门到精通

立即学习“PHP免费学习笔记(深入)”;

方案:不使用flock函数,借用临时文件来解决读写冲突的问题。

大致原理如下:

(1)将需要更新的文件考虑一份到我们的临时文件目录,将文件最后修改时间保存到一个变量,并为这个临时文件取一个随机的,不容易重复的文件名。

(2)当对这个临时文件进行更新后,再检测原文件的最后更新时间和先前所保存的时间是否一致。

(3)如果最后一次修改时间一致,就将所修改的临时文件重命名到原文件,为了确保文件状态同步更新,所以需要清除一下文件状态。

(4)但是,如果最后一次修改时间和先前所保存的一致,这说明在这期间,原文件已经被修改过,这时,需要把临时文件删除,然后返回false,说明文件这时有其它进程在进行操作。

实现代码如下:

代码如下:

$dir_fileopen='tmp';function randomid(){    return time().substr(md5(microtime()),0,rand(5,12));}function cfopen($filename,$mode){    global $dir_fileopen;    clearstatcache();    do{  $id=md5(randomid(rand(),TRUE));        $tempfilename=$dir_fileopen.'/'.$id.md5($filename);    } while(file_exists($tempfilename));    if(file_exists($filename)){        $newfile=false;        copy($filename,$tempfilename);    }else{        $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{        unlink($tempfilename);  //说明有其它进程 在操作目标文件,当前进程被拒绝        $success=false;    }    return $success;}$fp=cfopen('lock.txt','a+');cfwrite($fp,"welcome to beijing.");fclose($fp,'on');

登录后复制

对于上面的代码所使用的函数,需要说明一下:

(1)rename();重命名一个文件或一个目录,该函数其实更像linux里的mv。更新文件或者目录的路径或名字很方便。但当我在window测试上面代码时,如果新文件名已经存在,会给出一个notice,说当前文件已经存在。但在linux下工作的很好。

(2)clearstatcache();清除文件的状态.php将缓存所有文件属性信息,以提供更高的性能,但有时,多进程在对文件进行删除或者更新操作时,php没来得及更新缓存里的文件属性,容易导致访问到最后更新时间不是真实的数据。所以这里需要使用该函数对已保存的缓存进行清除。

以上就是php怎么解决多进程同时写一个文件的问题?的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2137317.html

(0)
上一篇 2025年2月25日 01:00:45
下一篇 2025年2月25日 01:01:10

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论