并发情况下,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内部调的是宿主文件系统,自然会把锁请求排队处理。
相关推荐
在PHP中,flock()是一个文件锁定的函数,用于防止多个进程同时对同一个文件执行写操作,从而避免数据的损坏。本文将详细介绍flock()函数的作用、参数以及使用时需要注意的事项。 首先,flock()函数的主要作用是在...
这里我们将详细探讨标题和描述中提到的一些关键的PHP文件操作函数。 1. **basename()**:这个函数从给定的路径中返回最后一个部分,即文件名。例如,`basename("/path/to/my/file.txt")`将返回`"file.txt"`。 2. *...
需要注意的是,Windows的文件锁定机制与Unix/Linux的`flock()`有所不同,可能会导致一些兼容性问题。例如,Windows的文件锁是基于字节范围的,而`flock()`通常是针对整个文件的。因此,如果你的程序需要在Unix/Linux...
flock()是PHP中用于文件加锁的一个函数,它提供了一种简单的方法来控制多个进程对同一文件的访问,防止文件内容出现混乱。 flock()函数允许你在任何平台上执行一个简单的读取/写入模型。这意味着,无论是在Unix派生...
虽然这种模拟方法可以实现在没有`flock()`的情况下进行文件锁定,但也存在一些局限性: - **性能问题**:频繁地创建和删除临时文件可能会带来一定的性能开销。 - **安全性问题**:由于使用的是文件系统级别的锁定...
在PHP中,flock函数就是用于实现文件锁定的一种机制。 flock是PHP提供的一个轻量级的咨询文件锁定功能。这种锁定是咨询式的,意味着它依赖于所有访问程序都必须采用相同的方式进行锁定,即它们必须都调用flock函数...
文件读取:`PHP_Read` 函数 此函数用于读取指定文件的内容,并返回整个文件的字符串。 **函数定义**: ```php function PHP_Read($file_name) { $fd = fopen($file_name, 'r'); while ($bufline = fgets($fd, ...
2. **flock() 函数**:PHP 的 `flock()` 函数用于锁定或解锁文件,接受两个参数,第一个是文件句柄,第二个是锁定类型(如 `LOCK_EX`、`LOCK_SH`、`LOCK_UN` 和 `LOCK_NB`)。 3. **阻塞与非阻塞**:阻塞模式会挂起...
如果 `$u2u` 参数为1,则先调用 `PHP_Read` 读取PHP文件内容,否则直接使用 `$filefrom` 的内容。然后调用 `PHP_Write` 将数据写入目标文件 `$fileto`,返回 `true` 表示成功。 4. **指定条件信息数量检索函数**: ...
在实际应用flock算法时,还需要考虑一些额外的因素,比如边界条件的处理(如何让群体在碰到边界时自然地反弹),个体之间的交互距离(影响群体的紧密程度),以及环境因素的影响(例如障碍物的避开)等。这些细节的...
其次,PHP文件锁定是确保文件在被多个脚本访问时保持一致性的关键。PHP提供了flock函数,用于对文件进行读写锁操作。在进行文件操作之前,先锁定文件可以防止其他进程在同一时刻修改文件内容,从而避免数据冲突。读...
`phptohtm` 函数用于将PHP文件转换为HTML静态页面。它可以通过读取PHP文件内容或直接使用提供的字符串 `$filefrom`,然后使用 `PHP_Write` 写入到 `$fileto` 文件中。这有助于提高网站性能,因为静态页面不需要...
标题 "php lock.zip_php_php lockit" 暗示了这是一个关于PHP文件锁定的压缩包,其中包含了与实现或理解PHP文件锁定机制相关的资源。文件描述 "php lock for php file" 进一步证实了这一点,它表明我们可能在探讨如何...