`

php文件函数flock

阅读更多

        并发情况下,PHP该如何写文件?其实这个问题不只是PHP面临的问题。不管是线程还是进程,当并发写的时候,都会遇到共享资源写冲突。软件开发过程中,写冲突无处不在,比如多线程写共享变量,比如数据库多连接并发写数据,比如多进程写文件等等。那么这些都该如何处理呢?目前普遍的处理办法就是给共享资源上独占锁(写锁)。

        PHP在第三版的时候就提供了一个函数flock,顾名思义,文件锁操作函数。文件锁机制是依赖于宿主文件系统的,也就是说,如何个锁法,是宿主文件系统说了算,flock只是个外壳函数,里面调用了文件系统的锁机制。

        锁的话,分为两种类型,读锁和写锁。写锁也叫排它锁、独占锁,就是一个线程或进程独占资源,别的线程或进程无法使用资源,保证写数据不受干扰,不冲突;读锁也叫共享锁,允许多个线程或进程同时读,但不能有写的操作。

函数原型:

 

<?php
flock ($handle, $operation, &$wouldblock = null);
?>

 

参数说明:

$handle //文件指针

$operation //锁类型

$operation 有几个可用值:LOCK_EX【写锁】、LOCK_SH【读锁】、LOCK_UN【释放锁】

        看个例子吧

 

<?php
function fileWrite($file)
{
	$fp = fopen($file, 'a');
	flock($fp, LOCK_EX);//上写锁
	/*写数据*/
	fwrite($fp, "1");
	fwrite($fp, "2");
	fwrite($fp, "3\r\n");
	flock($fp, LOCK_UN);//释放锁
	fclose($fp);
}
fileWrite('D:/txt.txt');
?>
        用Jmeter做下并发测试,执行3000次请求,会发现文件里有3000行123(不考虑apache或nginx的性能瓶颈)。

 

        在用Jmeter做并发测试的时候,用记事本打开这个文件,改点东西,然后点击保存,你会发现下图情况



        这就是因为文件上锁了,记事本进程无法写入。

        前边说了,flock函数的锁机制实际上是文件系统的锁机制,它封装了某些类型文件系统的锁机制,有些文件系统flock不支持,据PHP手册上说,FAT、NTF等这种老式文件系统和网络文件系统,flock不支持。本人没测过。

        PHP手册还说,flock是进程级别的,多线程的时候不起作用。可能大家就要有疑惑了,PHP又没线程的概念。那把PHP放在支持多线程的服务器上呢,大家想想看。测一测。

分析到这一步呢,会发现flock依赖宿主,对环境有要求,这就深深的伤害了代码的可移植性。怕啦!!别怕,其实伤害也没多深,flock还是能满足大部分环境的。

 

        针对flock的移植性稍有些不足,大家就开始研究替代办法,我也关注了下,发现网上流传着下面这样的代码

 

<?php
function fileWrite($file,$content)
{
	$lock = $file.'.lock';
	while (true) {
		if (file_exists($lock)) {
			usleep(100);
		}
		else
		{
			touch($lock);//上锁
			file_put_contents($file, $content, FILE_APPEND);//写文件
			@unlink($lock);//删除锁
			break;
		}
	}
}
fileWrite('D:/txt.txt','i m a phper');
?>

        你觉着这段代码有锁作用么??测测!!其实都不用测,一看就锁不住,file_exists本来就可以并行执行,当两进程同时执行到file_exists,判断所谓的锁文件不存在,结果还不是冲突着呢。

锁,实际上是将并发访问排队阻塞串行化,然后依次处理访问,上边这段代码连排队都没有,怎么能上锁呢。

    这时候大家可能又会问多个进程同时执行flock,不也是并行的么?是,执行flock是并行的,这只是代表申请锁是并行的,flock内部调的是宿主文件系统,自然会把锁请求排队处理。

 

  • 大小: 19.8 KB
分享到:
评论

相关推荐

    PHP文件锁函数flock()详细介绍

    主要介绍了PHP文件锁函数flock()详细介绍,本文着重对flock函数的作用和参数讲解,以及使用需要注意的问题,需要的朋友可以参考下

    PHP flock 文件锁详细介绍

    脚本之家小编今天将为大家详解关于php中文件锁函数flock函数用法简介,希望通过本文的介绍大家对于Linux方面能够更加的了解

    Perl 实例精解(第三版).pdf

    9.1.7 使用flock锁住文件 9.1.8 seek和tell函数 9.1.9 打开文件读写 9.1.10 管道打开 9.2 传送参数 9.2.1 ARGV数组 9.2.2 ARGV和Null文件句柄 9.2.3 eof函数 9.2.4 -i开关:原位编辑文件 ...

    PHP 常用函数库和一些实用小技巧

    文件读取函式 //文件读取函式 function PHP_Read($file_name) { $fd=fopen&#40;$file_name,r&#41;; while($bufline=fgets($fd, 4096)){ $buf.=$bufline; } fclose($fd); return $buf; } ?&gt; 文件写入函式 //文件...

    PHP常用技巧总结(附函数代码)

    PHP文件读取函式 复制代码 代码如下: //文件读取函式 function PHP_Read($file_name) { $fd=fopen&#40;$file_name,r&#41;; while($bufline=fgets($fd, 4096)){ $buf.=$bufline; } fclose($fd); return $buf; } ?&gt;...

    lock:PHP 中简单的面向对象文件锁管理

    锁 标准的 PHP flock函数很难测试。 这个库为flock提供了一个现代的、面向对象的包装器。安装将以下内容添加到您的composer.json : { " require " : { " benconstable/lock " : " ~1.0 " }}用法 &lt;?php$ lock = ...

    PHP对文件进行加锁、解锁实例

    本文提供了文件加锁函数以及使用示例。文件加锁功能也可以用来获得独享的处理空间,防止脚本执行发生同步错误。 复制代码 代码如下: &lt;?php /******************************************************************...

    网络安全ppt(1).pptx

    对抗网络扫描的手段 系统补丁Patch 禁止与系统服务信息有关的回应 停止系统服务 安装防火墙软件或者个人防火墙软件 使用入侵检测系统 提供系统安全的日志和审计功能 一些小而有效的技巧 网络安全ppt(1)全文共65页,...

    网络安全ppt(2).pptx

    对抗网络扫描的手段 系统补丁Patch 禁止与系统服务信息有关的回应 停止系统服务 安装防火墙软件或者个人防火墙软件 使用入侵检测系统 提供系统安全的日志和审计功能 一些小而有效的技巧 网络安全ppt(2)全文共65页,...

Global site tag (gtag.js) - Google Analytics