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. Mynavi Programming Contest 2021(AtCoder Beginner Contest 201)A ~ E题题解

    A - Tiny Arithmetic Sequence 水题,判断3个数是否能构成等差数列 void solve() { int a, b, c; cin >> a >> b ...

  2. 活动回顾|阿里云云原生 Serverless 技术实践营 深圳站回放&PPT下载

    11月24日"阿里云云原生 Serverless 技术实践营"深圳站圆满落幕.活动受众以关注  Serverless 技术的开发者.企业决策人.云原生领域创业者为主,活动形式为演讲 ...

  3. 【驱动】ifconfig up后内核网络驱动做了什么.md

    背景 最近在排查一个网络问题,ifconfig eth0 up 后,网卡link up比较慢.因此,分析了下从ifconfig up 到网络驱动的调用流程.这里顺便作个记录. ifconfig eth ...

  4. 机器学习-无监督机器学习-密度聚类DBSCAN-19

    目录 1. DBSCAN 2. OPTICS 2. MeanShift 1. DBSCAN Density based clustering DBSCAN不要求我们指定cluster簇的数量,避免了异 ...

  5. HTTP协议六种请求:GET,HEAD,PUT,DELETE,POST

    Http定义了与服务器交互的不同方法,标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD 6.Options 最基本的方法有4种,分别是GET ...

  6. linux tcpdump 使用小结(一)

    转载请注明出处: 很多情况在服务联调和定位过程中,需要在服务器上进行抓包进行问题定位.在Linux环境上使用tcpdump命令进行抓包: 1.tcpdump -s 0 -l -i any -w - p ...

  7. 13个构建RESTful API的最佳实践

    前言 Facebook.GitHub.Google和其他许多巨头都需要一种方法来服务和消费数据.在今天的开发环境中,RESTful API仍然是服务和消费数据的最佳选择之一. 但你是否考虑过学习行业标 ...

  8. 如何将一个JAR包添加到Java应用程序的Boot Classpath中?

    1. 在启动脚本中使用-bootstrap或-Xbootclasspath选项 这两个选项的使用方式如下: -bootstrap选项: java -bootstrap /path/to/your.ja ...

  9. ingress nginx 支持的K8S版本以及nginx版本信息

  10. [转帖]聊聊hikari连接池的leakDetectionThreshold

    http://www.manongjc.com/detail/52-hjoufmsfhtsqvgp.html 本文章向大家介绍聊聊hikari连接池的leakDetectionThreshold,主要 ...