学习笔记之PHP文件锁(flock)
来源:互联网 发布:数据网络开关 编辑:程序博客网 时间:2024/05/22 17:29
文件锁函数:
bool flock ( int $handle , int $operation [, int &$wouldblock ] )参数说明:
$handle 是已经打开的文件句柄;
$operation 可以是"LOCK_SH"(共享锁定)、"LOCK_EX"(排它锁定)、"LOCK_UN"(释放锁定)、"LOCK_NB"(防止flock锁定时堵塞)
代码示例分析:
1.两个进程同时向一个文件下数据
flocka.php
$file = 'test.txt';$fp = fopen($file,'a');if($fp){ for($i = 0;$i < 5;$i++) { fwrite($fp, "aaaaaaaa\n"); sleep(1); }}fclose($fp);flockb.php$file = 'test.txt';$fp = fopen($file,'a');if($fp){ for($i = 0;$i < 5;$i++) { fwrite($fp, "bbbbbbbb\n"); }}fclose($fp);
在浏览器上运行flocka.php后马上运行flockb.php文件,在test.txt文件中我们看到结果是:
aaaaaaaa
aaaaaaaa
aaaaaaaa
bbbbbbbb
bbbbbbbb
bbbbbbbb
bbbbbbbb
bbbbbbbb
aaaaaaaa
aaaaaaaa
奇怪了,flocka.php文件还未写完,flockb.php文件就执行了,造成数据混乱!
这种情况我们该如何处理呢? 解决方案就是对每个写进程加排他锁LOCK_EX,我们对两个php文件进行修改如下:
flocka.php
$file = 'test.txt';$fp = fopen($file,'a');if(flock($fp,LOCK_EX)){ for($i = 0;$i < 5;$i++) { fwrite($fp, "aaaaaaaa\n"); sleep(1); } flock($fp,LOCK_UN);}fclose($fp);flockb.php$file = 'test.txt';$fp = fopen($file,'a');if(flock($fp,LOCK_EX)){ for($i = 0;$i < 5;$i++) { fwrite($fp, "bbbbbbbb\n"); } flock($fp,LOCK_UN);}fclose($fp);
同样的操作步骤后,我们可以看到flockb.php文件并未先于flocka.php文件执行完,而现在test.txt的数据为:
aaaaaaaa
aaaaaaaa
aaaaaaaa
aaaaaaaa
aaaaaaaa
bbbbbbbb
bbbbbbbb
bbbbbbbb
bbbbbbbb
bbbbbbbb2.一个进程写数据,另一个进程读数据
flockc.php$fp = fopen("test.txt","a");if($fp){ fwrite($fp,"aaaaaa"); sleep(10); fwrite($fp,"bbbbbb");}else{ echo "文件打开失败";}fclose($fp);flockd.php$fp = fopen("test.txt","r");if($fp){ echo(fread($fp,1000)); fclose($fp);}else{ echo "文件打开失败!";}测试步骤: 在浏览器上运行flockc.php,然后马上运行flockd.php你将会看到flockc.php处于执行中,而flockd.php页面输出 aaaaaa当flockc.php执行完后,再执行flockd.php,该页面会输出aaaaaabbbbbb由此我们得知在flockc.php正在写数据时,flockd.php获取到的是脏数据!我们应该怎样避免这种情况呢?结合上一个demo的知识,对写加上排它锁,flockc.php代码如下:$fp = fopen("test.txt","a");if($fp){ flock($fp,LOCK_EX); fwrite($fp,"aaaaaa"); sleep(10); fwrite($fp,"bbbbbb"); flock($fp,LOCK_UN);}else{ echo "文件打开失败";}fclose($fp);继续相同的测试步骤,你会发现,在flockc.php正在执行时,运行flockd.php不会输出任何内容。这不是我想要的结果,再对flockd.php进行修改,代码如下:flockd.php$fp = fopen("test.txt","r");if(flock($fp,LOCK_SH)){ echo(fread($fp,1000)); flock($fp,LOCK_UN); fclose($fp);}else{ echo "文件打开失败!";}测试结果是:flockd.php会等到flcokc.php执行完后输出aaaaaabbbbbb有一位师兄的总结得很好:读的时候:如果不想出现dirty数据,那么最好使用lock_sh共享锁。可以考虑以下三种情况:1. 如果读的时候没有加共享锁,那么其他程序要写的话(不管这个写是加锁还是不加锁)都会立即写成功。如果正好读了一半,然后被其他程序给写了,那么读的后一半就有可能跟前一半对不上(前一半是修改前的,后一半是修改后的)2. 如果读的时候加上了共享锁(因为只是读,没有必要使用排他锁),这个时候,其他程序开始写,这个写程序没有使用锁,那么写程序会直接修改这个文件,也会导致前面一样的问题3. 最理想的情况是,读的时候加锁(lock_sh),写的时候也进行加锁(lock_ex),这样写程序会等着读程序完成之后才进行操作,而不会出现贸然操作的情况写的时候:如果多个写程序不加锁同时对文件进行操作,那么最后的数据有可能一部分是a程序写的,一部分是b程序写的如果写的时候加锁了,这个时候有其他的程序来读,那么他会读到什么东西呢?1. 如果读程序没有申请共享锁,那么他会读到dirty的数据。比如写程序要写a,b,c三部分,写完a,这时候读读到的是a,继续写b,这时候读读到的是ab,然后写c,这时候读到的是abc.2. 如果读程序在之前申请了共享锁,那么读程序会等写程序将abc写完并释放锁之后才进行读。本文学习地址:http://www.cnblogs.com/chenwenbiao/archive/2011/08/01/2123905.html
0 0
- 学习笔记之PHP文件锁(flock)
- PHP flock文件锁
- php flock之文件锁定
- PHP文件锁解析 flock()
- php 文件锁flock使用
- 文件锁之flock()函数
- 文件锁之flock()函数
- PHP flock文件锁详解介绍
- PHP flock 文件锁详细介绍
- PHP flock 文件锁详细介绍
- Linux编程中的文件锁之flock
- Linux编程中的文件锁之flock
- PHP flock实现文件加锁
- php 文件锁定详解flock
- PHP flock实现文件加锁
- 文件锁 flock及fcntl flock
- Linux文件锁flock
- Linux flock 文件锁
- Linux Shell学习小记 - function, here document, if statement, declare constant
- Hadoop生态系统
- 重定向redirect与转发forward的区别
- 项目开发计划——机房收费系统
- 设计模式
- 学习笔记之PHP文件锁(flock)
- 会话的两大技术Session和Cookie的区别
- 网络编程基础问题
- 庞峰Opencv学习(四)--颜色空间转换
- java的面向对象
- 动态规划的优化
- 软件工程——需求分析
- 全排列之字典序法
- Google File System架构