多个线程同时写入一个文件问题------php

在网上看到一道题,是这样问的,“写个函数来解决多线程同时读写一个文件的问题” 

上边给的答案是:flock($hander,LOCK_EX)

这个我想了下,感觉很不解,flock锁住当前文件时(第一个进程还未写入完),当下一个进程访问的时候就能写入了么?所以做了下测试

 写了两个文件

demo.php

<? php
$fp   =   fopen ( ' asn.php ' ,   ' w+ ' );
flock ( $fp ,  LOCK_EX);
sleep ( 10 );
flock ( $fp ,  LOCK_UN);
fclose ( $fp );
?>


demo1.php

$fp   =   fopen ( ' asn.php ' ,   ' w+ ' );
fwrite ( $fp ,   ' WriteOk! ' );
fclose ( $fp );


先运行,demo.php, 然后运行demo1.php,发现不能插入,所以依然质疑这个答案。

 

以前其实也遇到过这个问题,是个短信投票的接口,用了个不太主流的方法,当时也没出什么问题,可能是没到出错的量级吧。

 

function  add_num(  $file_path   ,   $messageid   ,   $num ){
         
$file_path_user   =   $file_path   .   ' / '   .   $messageid ; // 把路径加上被投人ID,去往被投人的文件夹
          while ( file_exists ( $file_path_user   .   ' /NO_WRITABLE ' )){}
           
// 为防止并发写入文件错误,判断一个文件是否存在,若存在证明正在插入,进入死循环,否则直接插入
         touch ( $file_path_user   .   ' /NO_WRITABLE ' ); // 新建验证文件
         file_put_contents $file_path_user . ' /num.txt ' ,  
                   
intval ( file_get_contents ( $file_path_user . ' /num.txt ' ))  +   $num
         );
// 增加票数
         unlink ( $file_path_user .   ' /NO_WRITABLE ' ); // 删除验证文件
}

 

这个方法用个新文件来标记是否插入完成,如果完成就插入正常插入下一条,如果没完成则进入死循环,这个需要把php文件的运行时间调高点(怕你插入的三国演义那种大东东,下一个进程会因为这个进程没结束而直至进行到php设置的最大运行时间而报错)

一个朋友说,可以在内存里做个标记,来替换掉文件标记,但试了半天不知道用什么方法实现。

希望那位知道的大侠回个可用的方法。我知道后也会更新此贴!

 

你可能感兴趣的:(PHP)