文件锁 - PHP 读文件怎么实现加锁
怪我咯
怪我咯 2017-04-10 14:24:04
[PHP讨论组]

有大量文件需要处理。
用一个php进程去操作会很慢。

如何在一个进程读某一个文件的时候,把文件锁上。
不让其他进程可以再读而直接跳过,继续读其他的?

把正在读得文件rename,读完之后再rename回来,效率挺低的。如果实在没有更好的方法,就只能用这个了。
flock,测试了一下,貌似不太好用,试了一下,没实现文件的非阻塞读锁。
给不同进程分配不同的文件,不好实现。
也没数据库。就算有。用数据库做锁,貌似比rename更低效。

请问有什么更好的方式可以给文件加 读锁。因为,只需要读文件。

怪我咯
怪我咯

走同样的路,发现不同的人生

全部回复(4)
PHP中文网

你的问题是:
1. 很多文件,想多进程处理,以提高效率,缩短总处理时间
2. 这些进程只需要读文件,不需要写
3. 对每个文件,只要有一个进程处理过它就可以了,没有多个进程都必须处理它的需求

你的需求其实是分治,将文件分为多个组(不一定要在文件系统上新建目录),然后分而治之,这种情况不需要用锁.

锁不是用于这种场景的,锁用于下面这种场景:

1. 文件file.txt里面记录了user1的销售额和user2的销售额,user1+user2的销售总额
2. 进程php1负责写入user1的数据,进程php2负责写入user2的数据,两个进程各读出销售总额显示给user1,user2
3. user1和user2同时要求写入,真的是同时,不是前后差个几秒什么的

建议你这样解决:
1. 启动多个PHP进程(nohup php your_script.php your_dir &)
2. 每个PHP进程赋予一个序号(假设4个进程,那就0,1,2,3),可以通过对进程自身的pid模运算取余数得到,也可以在启动进程的时候通过命令行传入,随你了
3. 每个进程在处理文件前先对文件名做crc32()运算,模一下进程总数: crc32(file_name) % 4, 取模结果与此进程的序号相等就读取内容并处理,不相等就跳过

最后:小编帮我排个版吧...

怪我咯

1. 为什么你会觉得rename效率低呢?如果一个目录下的文件不是相当多的话,这个应该不低。

2. 你肯定没有好好看flock的文档.

如果不希望 flock() 在锁定时堵塞,则给 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中设置为 4)。
巴扎黑

用memcached实现吧。

比如读取文件 $filename = "t.txt";

if(!$memcached->get($filename)){
   //文件锁不存在,那么执行文件读取功能
   //首先再将文件锁住,
   $memcaced->save($filename,'1');
   $fs = fopen($filename,'r+');
   
   fclose($fs);
   //读取完毕释放文件锁
   $memcaced->delete($filename);
}else{
   // 文件锁已经存在,跳过
   
}

以上是 memcaced 纯内存操作,速度会很快,根本不要考虑到性能的问题,当然还有一种方法,采用真正的文件锁,即添加一个新文件的方法控制,文件争用,但是此方法将加大IO的开销。

伊谢尔伦

最简单解决办法,一共俩文件,一个write,一个read。reader完了等writer close了就对调文件名。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号