PHP文件锁用法详解
发布:smiling 来源: PHP粉丝网 添加日期:2014-03-03 13:03:47 浏览: 评论:0
PHP出现文件锁与mysql表锁有大概想的用法,就是同一时间只能让一个人操作,这样就避免了同时有多个人操作同一文件,这样导致数据丢失的情况了,下面我来给大家介绍PHP文件锁用法.
PHP自带了文件锁函数:
bool flock ( int $handle , int $operation [, int &$wouldblock ] )
$handle 是打开的文件指针;
$operation 可以是
“LOCK_SH”,共享锁定;“LOCK_EX”,独占锁定;“LOCK_UN”,释放定;“LOCK_NB”,防止flock锁定时堵塞.这里主要说说“LOCK_EX”和“LOCK_NB”.
比如我们有两个文件,如下.
flocka.php
实例代码如下:
- $file = 'temp.txt';
- $fp = fopen($file,'a');
- for($i = 0;$i < 5;$i++)
- {
- fwrite($fp, "11111111n");
- sleep(1);
- }
- fclose($fp);
flockb.php
实例代码如下:
- $file = 'temp.txt';
- $fp = fopen($file,'a');
- for($i = 0;$i < 5;$i++)
- {
- fwrite($fp, "22222222n");
- }
- fclose($fp);
先运行flocka.php,然后马上运行flockb.php.
结果:
说明不加文件锁时,两个文件会同时对txt文件进行写入操作.
下面修改一下两个php文件的代码.
flocka.php
实例代码如下:
- $file = 'temp.txt';
- $fp = fopen($file,'a');
- if(flock($fp,LOCK_EX))
- {
- for($i = 0;$i < 5;$i++)
- {
- fwrite($fp, "11111111n");
- sleep(1);
- }
- flock($fp,LOCK_UN);
- }
- fclose($fp);
flockb.php
实例代码如下:
- $file = 'temp.txt';
- $fp = fopen($file,'a');
- if(flock($fp,LOCK_EX))
- {
- for($i = 0;$i < 5;$i++)
- {
- fwrite($fp, "22222222n");
- }
- flock($fp,LOCK_UN);
- }
- fclose($fp);
同样先运行flocka.php,然后马上运行flockb.php.
会发现在flocka.php运行结束前,flockb.php一直处于等待状态,只有当flocka.php运行结束后,flockb.php才会继续执行.
输出结果:
另外,在执行flock时,文件锁会自动释放.
还有一种办法,如下代码简单模拟了这种事务并发状态: process1.php
实例代码如下:
- <?php
- $num = 100;
- $filename = "processdata.txt";
- $fp = fopen($filename, "a");
- for ($i = 0; $i < $num; $i++) {
- fwrite($fp, "process1: " . $i . "rn");
- usleep(100000);
- }
- fclose($fp);
- ?>
我们需要先执行第一个事务,在processdata.txt文件中写入这100行.
process2.php
实例代码如下:
- <?php
- $num = 100;
- $filename = "processdata.txt";
- $fp = fopen($filename, "a");
- for ($i = 0; $i < $num; $i++) {
- fwrite($fp, "process2: " . $i . "rn");
- usleep(100000);
- }
- fclose($fp);
- ?>
第二个事务,继续向processdata.txt文件中写入100行.
多次同时执行,虽然都写了100行,但是事务1和事务2的数据交错写入,这并不是我们想要的结果.我们要的是事务完整的执行,此时我们需要有个机制去保证在第一个事务执行完后再执行第二个.在PHP中,flock函数完成了这一使命.在事物1和事务2的循环前面都加上: flock($fp, LOCK_EX); 就能满足我们的需求,将两个事务串行.
当某一个事务执行完flock时,因为我们在这里添加的是LOCK_EX(独占锁定),所以所有对资源的操作都会被阻塞,只有当事务执行完成后,后面的事务才会执行.我们可以通过输出当前的时间的方法来确认这一点.
关于在尾部追加写入,在unix系统的早期版本中存在一个并发写入的问题,如果要在尾部追加,需要先lseek位置,再write.当多个进程同时操作时,会因为并发导致的覆盖写入的问题,即两个进程同时获取尾部的偏移后,先后执行write操作,后面的操作会将前面的操作覆盖.这个问题在后面以添加打开时的O_APPEND操作而得到解决,它将查找和写入操作变成了一个原子操作.
在PHP的fopen函数的实现中,如果我们使用a参数在文件的尾部追加内容,其调用open函数中oflag参数为 O_CREAT|O_APPEND,即我们使用追加操作不用担心并发追加写入的问题.
在PHP的session默认存储实现中也用到了flock文件锁,当session开始时就调用PS_READ_FUNC,且以O_CREAT | O_RDWR | O_BINARY 打开session数据文件,此时会调用flock加上写锁,如果此时有其它进程访问此文件(即同一用户再次发起对当前文件的请求),就会显示页面加载中,进程被阻塞了.加写锁其出发点是为了保证此次会话中对session的操作事务能完整的执行,防止其它进程的干扰,保证数据的一致性.如果一个页面没有session修改操作,可以尽早的调用session_write_close()释放锁.
文件锁是针对文件的锁,除了这种释义,还可以理解为用文件作为锁.在实际工作中,有时为确保单个进程的执行,我们会在程序执行前判断文件是否存在,如果不存在则创建一个空文件,在进程结束后删除这个空文件,如果存在,则不执行.
Tags: PHP 文件 锁
相关文章
- ·php 读取目录所有文件信息dir()(2013-11-12)
- ·php获取当前文件所有执行的函数和类(2013-11-12)
- ·php检查文件是否可读和可写(2013-11-14)
- ·PHP文件操作方法问答 (2013-11-14)
- ·PHP 文件操作概述 (2013-11-14)
- ·php文件操作和获取文件信息数据 (2013-11-14)
- ·PHP开发中文件操作疑难问答(2013-11-27)
- ·php判断文件是否存在file_exists 与 is_file详解(2013-11-29)
- ·PHP 获取文件扩展名的方法(2013-11-29)
- ·PHP中读写文件(2013-11-29)
- ·PHP操作文件问答(2013-12-08)
- ·php 显示指定目录所有子文件夹(2013-12-11)
- ·php文件操作(2013-12-11)
- ·php判断文件是否存在(2013-12-16)
- ·php 浏览目录(2013-12-19)
- ·php如何获取文件夹大小程序代码(2014-01-05)
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)