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. 【每日一题】35. [CQOI2009]中位数图 (前缀和,贡献值计算)

    补题链接:Here 算法涉及:前缀和,贡献值计算 经典中位数计数问题,记得以前百度之星也出过类似的题,这道题有一个限定范围是要奇数区间的 我们很容易想到,奇数下标到偶数下标或者偶数下标到奇数下标的长度 ...

  2. 4、SpringBoot连接数据库引入druid

    系列导航 springBoot项目打jar包 1.springboot工程新建(单模块) 2.springboot创建多模块工程 3.springboot连接数据库 4.SpringBoot连接数据库 ...

  3. 【新手友好】用Pyspark和GraphX解析复杂网络数据

    从零开始 在本文中,我们将详细介绍如何在Python / pyspark环境中使用graphx进行图计算.GraphX是Spark提供的图计算API,它提供了一套强大的工具,用于处理和分析大规模的图数 ...

  4. MES系统初探(一)

    什么是MES系统 MES系统是制造执行系统(Manufacturing Execution System)的缩写,是一种用于监控.控制和优化制造过程的软件系统.它主要负责协调生产计划.生产调度.生产执 ...

  5. VirtualBox 设置开机自动在后台启动虚拟机

    打开 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 新建文件 virtualbox.bat 编写脚本 "C:\Pr ...

  6. maven总结一: 常用命令

    本文为博主原创,未经允许不得转载: maven常用命令: 1. mvn clean  maven清理 2. mvn compile  maven 编译 3. mvn package maven 打包 ...

  7. 【MicroPython】生成Q(string)符号表文件 - py\makeqstrdefs.py

    脚本使用格式 python py/makeqstrdefs.py [command] [mode] [input-file] [output-directory] [output-file] comm ...

  8. 幻兽帕鲁 Palworld 私有服务器一键部署教程

    <幻兽帕鲁>(日语:パルワールド,英语:Palworld) 是由日本开发商 Pocket Pair 推出的一款动作冒险生存游戏.游戏设定在一个由类似动物的生物 "帕鲁" ...

  9. 【面试题精讲】JavaOptional用法

    有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 文章更新计划 系列文章地址 Java 8 引入了 Option ...

  10. 【面试题精讲】Java Stream排序的实现方式

    首发博客地址 系列文章地址 如何使用Java Stream进行排序 在Java中,使用Stream进行排序可以通过sorted()方法来实现.sorted()方法用于对Stream中的元素进行排序操作 ...