并发文件读写

9

当PHP接收到许多读写文件请求时会发生什么?这些请求会排队吗?还是只有一个请求被接受,其余请求将被丢弃?

我计划使用文本格式的点击计数器。


1
请查看我在flock使用方面的回答:这里。可能会有所帮助。 - Nemoden
3个回答

6
你可能会遇到竞态条件的问题。
为了避免这种情况,如果你只需要简单地追加数据,可以使用。
file_put_contents(,,FILE_APPEND|LOCK_EX);

不用担心数据完整性。

如果需要更复杂的操作,您可以使用 flock(用于简单的读写问题)。

对于您的 PHP 脚本计数器,我建议您像这样做:

//> Register this impression
file_put_contents( $file, "\n", FILE_APPEND|LOCK_EX );

//> Read the total number of impression
echo count(file($file));

这样,您就不必实现阻止机制,可以使系统和代码脚本更轻巧。
补充说明:
为了避免需要计算array file(),您可以使用以下方法使系统更加轻量级:
//> Register this impression
file_put_contents( $file, '1', FILE_APPEND|LOCK_EX );

//> Read the total number of impression
echo filesize($file);

基本上,要读取计数器的数量,您只需要读取其文件大小,每次展示会增加1个字节。

是的,我知道你可以为读/写操作锁定文件,但如果随后收到其他两个读取或写入请求,这些请求会被抛弃还是排队等候? - Sourav
使用file_append时,写请求当然会被排队。同时,读请求不会被阻塞。 - dynamic
也许他不只是想“追加”。使用写锁,你可以对文件进行任何修改,其他线程会被“排队”(而非抛出),直到锁被释放。 - BenMorel
这对我来说是新鲜事,通过文件大小计算点击量,但如果我的网站变成Facebook会发生什么?哈哈 :) - Sourav
1
@sourav:如果它变成了Facebook,也许你会开始使用像Google Analytics这样的东西^^ - dynamic
显示剩余4条评论

4
不,请求不会排队,读者将获得损坏的数据,写者将相互覆盖,数据将被损坏。 你可以尝试使用flockfopenx模式。
编写良好的锁定互斥体并不容易,因此请尝试查找现有变量,或尝试将数据从文件移动到数据库。

你有这个信息的来源吗?看起来和这里其他答案有矛盾,所以我想知道你是怎么知道的。 - Simon East
@OZ_,你是不是指的是 c 标志而不是 x 标志? - Pacerier

1

在读写文件之前,您可以使用flock()获取文件锁。如果其他线程持有文件锁,则flock()将等待直到其他锁被释放。


请纠正我,但是当有3个写入者同时存在时,flock不能保证锁的独占性...这种情况在多线程环境中经常发生(在fork模式或多线程模式下,无论如何),例如apache,FCGI等等...请求#1:flock(); fwrite();.. #2等待锁,fwrite... #3也在等待锁,同时fwrite... BAM,#2和#3同时写入...我说得对吗? - Dalibor Filus
在我看来,flock() 在操作系统级别上运行,应该是线程安全的。也许有更好的操作系统知识的人可以确认一下? - BenMorel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接