PHP中文件锁

文件锁的用途:

若一个人在写入一个文件,另外一个人同时也打个了这个文件进行写入文件。

这情况下,如果遇到一定的碰撞概率的话,不知道到底谁的操作为准。

因此,这个时候我们引入锁机制。

若用户A在写入或者读取这个文件的时候,将文件加上共享锁。我可以读,其他人也可以读。

但是,我如果这与的时候。我使用独占锁。这个文件归我了,你们都别动,除非我将文件锁进行释放。

注意:加上了文件锁后要注意释放

一、交叉写入

1、文件没有加锁

demo.php

header('content-type:text/html;charset=utf-8');
$filename = 'flock.txt';
$handle = fopen($filename,'a'); for($i=0;$i<1000000; $i++){
fwrite($handle,'x');
}

demo_b.php

header('content-type:text/html;charset=utf-8');
$filename = 'flock.txt';
$handle = fopen($filename,'a'); for($i=0;$i<1000000; $i++){
fwrite($handle,'b');
}

2、添加独占锁

demo.php

header('content-type:text/html;charset=utf-8');
$filename = 'flock.txt';
$handle = fopen($filename,'a');
flock($handle,LOCK_EX);
for($i=0;$i<1000000; $i++){
fwrite($handle,'x');
}

demo_b.php

header('content-type:text/html;charset=utf-8');
$filename = 'flock.txt';
$handle = fopen($filename,'a');
flock($handle,LOCK_EX);
for($i=0;$i<1000000; $i++){
fwrite($handle,'b');
}

二、关于阻塞

在PHP 5.3.2版本之前,锁会被 fclose() 释放(在脚本结束后会自动调用),现在需要手动解锁

锁方式 说明
LOCK_SH 取得共享锁(读取的程序)
LOCK_EX 取得独占锁(写入的程序)
LOCK_UN 释放锁定 (无论共享或独占)
LOCK_NB 在flock()锁定时不阻塞 windows不支持

实例1:A使用独占锁写文件,B读取文件,阻塞

a.php

$file = 'test.txt';
$fp = fopen($file, 'w'); if(flock($fp, LOCK_EX)){ // 取得独占锁
fwrite($fp, "Hello World\r\n"); // 写入数据
sleep(10); // sleep 10秒,文件被锁定
fwrite($fp, "Hello PHP\r\n"); // 写入数据
flock($fp, LOCK_UN); // 解锁
} fclose($fp);

b.php

$file = 'test.txt';
$fp = fopen($file, 'r'); if(flock($fp, LOCK_SH)){ // 取得共享锁
while(!feof($fp)){
echo fread($fp, 100);
}
flock($fp, LOCK_UN);
} fclose($fp);

先执行a.php,然后执行b.php a取得独占锁,b只能等待,等a执行完解除锁定后才能执行b,阻塞

实例2:A,B都使用共享锁,不阻塞

a.php

$file = 'test.txt';
$fp = fopen($file, 'r'); if(flock($fp, LOCK_SH)){ // 取得共享锁
sleep(10); // sleep 10秒
while(!feof($fp)){
echo fread($fp, 100);
}
flock($fp, LOCK_UN);
} fclose($fp);

b.php

$file = 'test.txt';
$fp = fopen($file, 'r'); if(flock($fp, LOCK_SH)){ // 取得共享锁
while(!feof($fp)){
echo fread($fp, 100);
}
flock($fp, LOCK_UN);
} fclose($fp);

先执行a.php,然后执行b.php

b不需要等待a执行完就能输出文件内容,非阻塞

实例3:A,B都使用独占锁写文件,阻塞

a.php

$file = 'test.txt';
$fp = fopen($file, 'a'); if(flock($fp, LOCK_EX)){ // 取得独占锁
fwrite($fp, "Hello World\r\n"); // 写入数据
sleep(10); // sleep 10秒,文件被锁定
fwrite($fp, "Hello PHP\r\n"); // 写入数据
flock($fp, LOCK_UN); // 解锁
} fclose($fp);

b.php

$file = 'test.txt';
$fp = fopen($file, 'a'); if(flock($fp, LOCK_EX)){ // 取得独占锁
fwrite($fp, "How Are You\r\n"); // 写入数据
fwrite($fp, "Show Me The Money\r\n"); // 写入数据
flock($fp, LOCK_UN); // 解锁
} fclose($fp);

先执行a.php,然后执行b.php

b需要等待a执行完,才能写入数据,阻塞

实例4:LOCK_NB 锁定时不阻塞,不等待

a.php

$file = 'test.txt';
$fp = fopen($file, 'a'); if(flock($fp, LOCK_EX)){ // 取得独占锁
fwrite($fp, "Hello World\r\n"); // 写入数据
sleep(10); // sleep 10秒,文件被锁定
fwrite($fp, "Hello PHP\r\n"); // 写入数据
flock($fp, LOCK_UN); // 解锁
} fclose($fp);

b.php

$file = 'test.txt';
$fp = fopen($file, 'a'); if(flock($fp, LOCK_EX|LOCK_NB)){ // 取得独占锁
fwrite($fp, "How Are You\r\n"); // 写入数据
fwrite($fp, "Show Me The Money\r\n"); // 写入数据
flock($fp, LOCK_UN); // 解锁
}else{
echo 'file locked';
} fclose($fp);

先执行a.php,然后执行b.php

b取不到独占锁,不需要等待a执行完,而是直接返回取不到锁提示,非阻塞

总结

使用共享锁LOCK_SH,如果是读取,不需要等待,但如果是写入,需要等待读取完成。

使用独占锁LOCK_EX,无论写入/读取都需要等待。

LOCK_UN,无论使用共享/读占锁,使用完后需要解锁。

LOCK_NB,当被锁定时,不阻塞,而是提示锁定。

PHP中文件锁的更多相关文章

  1. PHP中文件锁与进程锁的使用区别

    php中文网的一篇文章,收为己用了.源地址: http://www.php.cn/php-weizijiaocheng-376853.html 本篇文章主要介绍了PHP 文件锁与进程锁的使用示例,小编 ...

  2. Linux 2.6 中的文件锁

    简介: 本文的目的是想帮助读者理清 Linux 2.6中文件锁的概念以及 Linux 2.6 都提供了何种数据结构以及关键的系统调用来实现文件锁,从而可以帮助读者更好地使用文件锁来解决多个进程读取同一 ...

  3. php flock 文件锁

    于php中文件锁函数flock函数用法简介,希望通过本文的介绍大家对于Linux方面能够更加的了解 flock (PHP 4, PHP 5) flock — 轻便的咨询文件锁定 说明 bool flo ...

  4. linux内核情景分析之内核中的互斥操作

    信号量机制: struct sempahore是其结构,定义如下 struct semaphore { atomic_t count;//资源数目 int sleepers;//等待进程数目 wait ...

  5. Secondary NameNode:的作用?

    前言 最近刚接触Hadoop, 一直没有弄明白NameNode和Secondary NameNode的区别和关系.很多人都认为,Secondary NameNode是NameNode的备份,是为了防止 ...

  6. Java NIO 内存映射文件

    Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...

  7. Java读取文件加锁代码Demo(利用Java的NIO)

    本博文部分转载于:http://blog.csdn.net/wangbaochu/article/details/48546717 Java 提供了文件锁FileLock类,利用这个类可以控制不同程序 ...

  8. Secondary NameNode 的作用

    https://blog.csdn.net/xh16319/article/details/31375197 很多人都认为,Secondary NameNode是NameNode的备份,是为了防止Na ...

  9. 12. Go 语言文件处理

    Go 语言文件处理 本章我们将带领大家深入了解一下 Go语言中的文件处理,重点在于文件而非目录或者通用的文件系统,特别是如何读写标准格式(如 XML 和 JSON 格式)的文件以及自定义的纯文本和二进 ...

  10. Python开源框架

    info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...

随机推荐

  1. 骨牌摆放问题 POJ 2411(状态压缩DP)

    题目: 给你\(n*m(1<=n,m<=11)\)的方格矩阵,要求用1*2的多米诺骨牌去填充,问有多少种填充方法. 比如下图是对于如下2x6的方格矩阵,可能的填充方案之一. 该如何使用动态 ...

  2. vivo悟空活动中台-打造 Nodejs 版本的MyBatis

    经典的架构设计可以跨越时间和语言,得以传承. -- 题记 一.背景 悟空活动中台技术文章系列又和大家见面了,天气渐冷,注意保暖. 在往期的系列技术文章中我们主要集中分享了前端技术的方方面面,如微组件的 ...

  3. 二、swift添加存储策略

    系列导航 一.swift对象存储环境搭建 二.swift添加存储策略 三.swift大对象--动态大对象 四.swift大对象--静态态大对象 五.java操作swift对象存储(官网样例) 六.ja ...

  4. C#查找算法1:二分查找

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法.但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列. 原理:将n个元素分成个数大致相同的两半,取 ...

  5. java基础-方法method-day05

    1. 语法 [修饰符] 返回值类型 方法名(形参列表){ 逻辑主体 } public class TestMethod01{ public static int add(int num1, int n ...

  6. java基础数据类型-int类型-浮点型-数据类型的转换--day02

    目录 1. 变量的命名 2. 常量 3. 变量 4. 进制 4.1 进制转换 4.2 整型数据类型 5 浮点型 6. 字符串 7. 整形与字符型之间的转换 8 最常见的一个乱码问题 9. 布尔类型 1 ...

  7. [译] kubernetes:kube-scheduler 调度器代码结构概述

    本文翻译自 https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduli ...

  8. Nacos源码 (1) 源码编译及idea环境

    本文介绍从gitee下载nacos源码,在本地编译,并导入idea进行本地调试. 从gitee下载源码 由于github访问速度慢,所以我选择使用gitee的镜像仓库: git clone https ...

  9. R语言—数据基础及练习

    ## 创建leadership数据框 manager <- c(1,2,3,4,5) date <-c("10/24/08","10/28/08", ...

  10. 使用Docker部署java项目时遇到的几个错误

    0.简介 本文主要是在学习黑马程序员Docker快速入门到项目部署过程中, 对遇到的问题进行了相关的总结梳理 1.本地已存在mysql服务占用3306端口 问题 当我使用docker run -d - ...