在网上看到一道题,是这样问的,“写个函数来解决多线程同时读写一个文件的问题”
上边给的答案是: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设置的最大运行时间而报错)
一个朋友说,可以在内存里做个标记,来替换掉文件标记,但试了半天不知道用什么方法实现。
希望那位知道的大侠回个可用的方法。我知道后也会更新此贴!