前言

1、锁机制之所以存在是因为并发问题导致的资源竞争,为了确保操作的有效性和完整性,可以通过锁机制将并发状态转换成串行状态。作为锁机制中的一种,PHP 的文件锁也是为了应对资源竞争。假设一个应用场景,在存在较大并发的情况下,通过fwrite向文件尾部多次有序的写入数据,不加锁的情况下会发生什么? 多次有序的写入操作相当于一个事务,我们此时需要保证这个事务的完整性。 
2、例如:同时执行下面两段代码,会发现虽然都写入了数据,但是是两段程序交错写入,很明显这并不是期望的结果。

public function demo50() {
$num = 10;
$filename = 'process.txt';
if ($fp = fopen($filename, 'a')) {
for ($i = 0; $i<= $num; $i++) {
fwrite($fp, 'process1:' . $i . "\r\n");
usleep(100000);
}
fclose($fp);
} else {
echo 'faile';
}
}

  

public function demo51() {
$num = 10;
$filename = 'process.txt';
if ($fp = fopen($filename, 'a')) {
for ($i = 0; $i<= $num; $i++) {
fwrite($fp, 'process2:' . $i . "\r\n");
usleep(100000);
}
fclose($fp);
} else {
echo 'faile';
}
}

  

public function demo53() {
// 创建一对cURL资源
$ch1 = curl_init();
$ch2 = curl_init(); // 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "http://local.thinkphp.com/index.php?h=home&c=index&a=demo50");
curl_setopt($ch2, CURLOPT_URL, "http://local.thinkphp.com/index.php?h=home&c=index&a=demo51"); // 创建批处理cURL句柄
$mh = curl_multi_init(); // 增加2个句柄
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2); $running = null;
// 执行批处理句柄
do {
curl_multi_exec($mh, $running);
} while ($running > 0); // 关闭全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
}

  

运行结果如下


加上文件锁后

public function demo50() {
$num = 10;
$filename = 'process.txt';
if ($fp = fopen($filename, 'a')) {
if (flock($fp, LOCK_EX)) {
for ($i = 0; $i<= $num; $i++) {
fwrite($fp, 'process1:' . $i . "\r\n");
usleep(100000);
}
flock($fp, LOCK_UN);
}
fclose($fp);
} else {
echo 'faile';
}
}

  

public function demo51() {
$num = 10;
$filename = 'process.txt';
if ($fp = fopen($filename, 'a')) {
if (flock($fp, LOCK_EX)) {
for ($i = 0; $i<= $num; $i++) {
fwrite($fp, 'process2:' . $i . "\r\n");
usleep(100000);
}
flock($fp, LOCK_UN);
}
fclose($fp);
} else {
echo 'faile';
}
}

  

PHP文件锁:

  摘自:http://www.cnblogs.com/ninelands/archive/2012/09/18/2690713.html

1、文件锁有两种:共享锁和排它锁,也就是读锁(LOCK_SH)和写锁(LOCK_EX); 
2、但是什么时候使用LOCK_SH什么时候使用LOCK_EX呢? 
读的时候: 
如果不想出现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写完并释放锁之后才进行读。

php文件锁的更多相关文章

  1. JAVA NIO简介-- Buffer、Channel、Charset 、直接缓冲区、分散和聚集、文件锁

    IO  是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. Java标准io回顾 在Java1.4之前的I/O系统中,提供 ...

  2. Linux文件锁flock

    Linux文件锁flock 在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要锁操作来保证数据的完整性,这里介绍的针对文件的锁,称之为“文件锁”-flock. flock,建议性锁 ...

  3. JAVA基础知识之NIO——Buffer.Channel,Charset,Channel文件锁

    NIO机制 NIO即NEW IO的意思,是JDK1.4提供的针对旧IO体系进行改进之后的IO,新增了许多新类,放在java.nio包下,并对java.io下许多类进行了修改,以便使用与nio. 在ja ...

  4. Linux 文件锁

    当多个进程同时访问操作同一个文件时,我们怎么保证文件数据的正确性. linux通常采用的方法是文件上锁,来避免共享资源的产生竞争状态. 文件锁包括建议性锁和强制性的锁: 建议性的锁 :顾名思义,相对温 ...

  5. php中并发读写文件冲突的解决方案(文件锁应用示例)

    PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适 ...

  6. php原子操作,文件锁flock,数据库事务

    php原子操作,文件锁flock,数据库事务 php没有继承posix标准支持的unix锁,只封装了一个linux系统调用flock(信号量也能做成锁),按理也是可以使用锁机制的,虽然效率低一点.ph ...

  7. linux文件锁

    http://blog.chinaunix.net/uid-25324849-id-3077304.html 在SHELL中实现文件锁,有两种简单的方式.(1)一是利用普通文件,在脚本启动时检查特定文 ...

  8. linux使用flock文件锁解决crontab冲突问题

    * * * * * flock -xn /dev/shm/redis.lock -c "/usr/local/bin/redis-server" 可以用flock命令,配合使用rs ...

  9. Linux同步机制(二) - 条件变量,信号量,文件锁,栅栏

    1 条件变量 条件变量是一种同步机制,允许线程挂起,直到共享数据上的某些条件得到满足. 1.1 相关函数 #include <pthread.h>  pthread_cond_t cond ...

随机推荐

  1. Java 加解密 AES DES TripleDes

    package xxx.common.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypt ...

  2. [Hadoop in Action] 第1章 Hadoop简介

    编写可扩展.分布式的数据密集型程序和基础知识 理解Hadoop和MapReduce 编写和运行一个基本的MapReduce程序   1.什么是Hadoop   Hadoop是一个开源的框架,可编写和运 ...

  3. Python写各大聊天系统的屏蔽脏话功能原理

    Python写各大聊天系统的屏蔽脏话功能原理 突然想到一个视频里面弹幕被和谐的一满屏的*号觉得很有趣,然后就想用python来试试写写看,结果还真玩出了点效果,思路是首先你得有一个脏话存放的仓库好到时 ...

  4. jmeter之连接mysql和SQL Server配置

    下载jdbc驱动 在使用jmeter做性能或自动化测试的时候,往往需要直接对数据库施加压力,或者某些参数只能从数据库获取,这时候就必须使用jmeter连接数据库. 1.下载对应的驱动包 mysql驱动 ...

  5. x01.MagicCube: 简单操作

    看最强大脑,发现魔方还是比较好玩的,便买了一个,对照七步还原法,居然也能成功还原. 为什么不写一个魔方程序呢?在网上找了找,略作修改,进行简单操作,还是不错的,其操作代码如下: protected o ...

  6. android onNewIntent调用时机

    (转自:http://www.cnblogs.com/zenfly/archive/2012/02/10/2345196.html) 在IntentActivity中重写下列方法:onCreate o ...

  7. [No000090]C#捕获控制台(console)关闭事件及响应cmd快捷键

    捕获控制台(console)关闭事件: 1.Ctrl+C信号: 2.Ctrl+Break信号: 3.用户系统关闭Console时: 4.用户退出系统时: 5.系统将要关闭时: using System ...

  8. struts2中各个jar包作用

    Struts2.3.4 所需的Jar包及介绍 Jar包的分类 jar包名称 jar包版本 jar包 文件名 jar包 的作用 jar包内包含的主要包路径及主要类 依赖的自有jar包名称 依赖的第三方j ...

  9. 时隔一年再读到the star

    The Star Arthur C. Clarke It is three thousand light-years to the Vatican. Once, I believed that spa ...

  10. [LeetCode] Find Right Interval 找右区间

    Given a set of intervals, for each of the interval i, check if there exists an interval j whose star ...