您的位置 首页 技术

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

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编程从入门到精通

方案:不使用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.\n");fclose($fp,'on');

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

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

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

以上就是php怎么解决多进程同时写一个文件的问题?的详细内容,更多请关注24课堂在线网其它相关文章!

本文来自网络,不代表24小时课堂在线立场,转载请注明出处:https://www.24ketang.cn/89460.html

为您推荐

返回顶部