首页 > 编程语言 >PHP中文件锁

PHP中文件锁

时间:2023-11-11 10:12:33浏览次数:35  
标签:fp 文件 php LOCK 写入 file flock PHP

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,当被锁定时,不阻塞,而是提示锁定。

标签:fp,文件,php,LOCK,写入,file,flock,PHP
From: https://www.cnblogs.com/ygcphp/p/17825562.html

相关文章

  • PHP 批量上传文件 大全
    案例一:<?php$file_path="uploads/";for($i=0;$i<count($_FILES[ufile][name]);$i++){  $_FILES[ufile][name][$i]=time().$_FILES[ufile][name][$i];//加个时间戳防止重复文件上传后被覆盖  }print_r($_FILES[ufile][name]);$filename=$_FILES[ufile][name];$filet=$_FIL......
  • 开始pyspark------------jupyter notebook 读取CSV文件
    1开始pyspark  1查看版本信息¶ In [1]:importsysprint(sys.version_info)  sys.version_info(major=3,minor=11,micro=5,releaselevel='final',serial=0) In [2]:importosprint("ThevalueofSPARK_H......
  • Linux常用命令——tar文件的压缩与解压缩
    tar   选项   包名    文件名tar本身没有压缩功能,只有打包功能,但是tar可以调用压缩工具;以下是常用命令:-c  创建归档文件-v  显示过程-x  展开归档文件-f  操作归档文件-C  指定解压路径-z  调用gzip压缩工具-j  调用bzip2压缩工具-J......
  • 有什么可以自动保存微信文件的方法么?
    8-3本文要介绍的方法,可以自动帮你保存微信上收到的文件型数据,比如文件、图片、视频,如果你的工作需要每天或者经常保存大量的从微信收到的文件型数据,也许本文适合你,本文介绍的工具,对微信多开也有效果,并且可以单独对某些群聊或者对话里的文件型数据做自动保存。 以下正文 首先要准......
  • 文件缓存的读写
     文件系统的读写,其实就是调用系统函数read和write。下面的代码就是read和write的系统调用,在内核里面的定义。SYSCALL_DEFINE3(read,unsignedint,fd,char__user*,buf,size_t,count){structfdf=fdget_pos(fd);......loff_tpos=file_pos_read(f.file)......
  • php安装扩展的几种方式
    转载:https://v3.test.zc10.cn/archives/4369相关资料: https://www.php.cn/faq/375900.html方法一、使用apt或者yum命令安装例如: yuminstallphp72w-bcmath安装7.2bc库, 然后使用php-m查看是否安装成功方法二、使用pecl安装方法三、源码编译安装(一般是安装PHP自......
  • 文件阅读器的使用——利用文件阅读器将选中的文件图片展示到前端页面
    代码示例:#HTML部分<formaction=""><divclass="form-group"><labelfor="id_file">用户头像{%loadstatic%}<imgsrc="{%static'img/default.png'......
  • 如何从文件路径中提取目录路径?
    内容来自DOChttps://q.houxu6.top/?s=如何从文件路径中提取目录路径?在Bash中,如果VAR="/home/me/mydir/file.c",我该如何获得"/home/me/mydir"?dirname和basename是您要用于提取路径组件的工具:$VAR='/home/pax/file.c'$DIR="$(dirname"${VAR}")";FIL......
  • openGauss学习笔记-119 openGauss 数据库管理-设置数据库审计-设置文件权限安全策略
    openGauss学习笔记-119openGauss数据库管理-设置数据库审计-设置文件权限安全策略119.1背景信息数据库在安装过程中,会自动对其文件权限(包括运行过程中生成的文件,如日志文件等)进行设置。其权限规则如下:数据库程序目录的权限为0750。数据库数据文件目录的权限为0700。ope......
  • Linux搭建文件服务器
    @目录基于centos7.9搭建http文件服务器基于centos7.9搭建nginx文件服务器基于ubuntu2204搭建http文件服务器IP环境192.168.200.100VMware17基于centos7.9搭建http文件服务器安装httpd[root@localhost~]#yuminstall-yhttpd关闭防火墙以及selinux[root@loc......