使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失

摘要:
使用PHP文件锁同时向一个文件写入多个请求。它不需要脏读取和数据丢失//并发文件操作functionfilehandle($filename,$data){$start=0;$end=3000;if(!file_exists($filename)){return“文件不存在”;}如果(!Is_string($data)){return“写入的内容只能是字符串类型”;}如果($fp=fopen

使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失.

//并发文件操作
function filehandle($filename,$data){
    $start = 0;
    $end = 3000;

    if(!file_exists($filename)){
        return "文件不存在";
    }

    if(!is_string($data)){
        return "写入内容只能为字符串类型";
    }

    if($fp = fopen($filename,'a')){
        do{
            //获取文件独占锁
            $canWrite = flock($fp,LOCK_EX);

            if(!$canWrite){
                $rand = mt_rand(1,100);
                //让程序休眠随机毫秒数再试
                usleep($rand*1000);
                $start += $rand;
            }

        }while(!$canWrite && $start < $end);

        if(!$canWrite){
            //未能获得锁
            return "获取文件锁失败";
        }else{
            fwrite($fp,$data);
        }

        //释放锁定,关闭文件
        flock($fp, LOCK_UN);
        fclose($fp);
        return true;

    }else{
        return "打开文件失败";
    }
    
}

此方法的要点是当用户操作文件的时候必须获取文件的独占锁,若文件已经被锁定,则让程序休眠若干毫秒后重试,知道获得锁或者超时为止。

flock():轻便的咨询文件锁定

函数参数说明:

handle - 文件系统指针,是典型地由 fopen() 创建的 resource(资源)。

operation - 可以是以下值之一:

  1. LOCK_SH 取得共享锁定(读取的程序)。
  2. LOCK_EX   取得独占锁定(写入的程序。
  3. LOCK_UN 释放锁定(无论共享或独占)。

返回值:成功时返回 TRUE, 或者在失败时返回 FALSE

方案二:

file_put_contents($filename, $data, FILE_APPEND|LOCK_EX);

int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] );

函数说明:将一个字符串写入文件

参数说明:

  filename - 要被写入数据的文件名。

  data - 要写入的数据。类型可以是 string,array(一维) 或者是 stream 资源。

  flags - flags的值可以是 以下 flag 使用 OR (|) 运算符进行的组合。

    FILE_USE_INCLUDE_PATH : 在 include 目录里搜索 filename。 更多信息可参见 include_path。
    FILE_APPEND : 如果文件 filename 已经存在,追加数据而不是覆盖。
    LOCK_EX : 在写入时获得一个独占锁。

  context - 一个 context 资源。

返回值:该函数将返回写入到文件内数据的字节数,失败时返回FALSE

(注:以上方案均未经过实际项目测试)

免责声明:文章转载自《使用PHP文件锁写一个多个请求同时并发写入一个文件,要求不脏读、数据不丢失》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[开源] C# 封装 银海医保的接口web(五)---spawn-fastcgi下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

php的session

来源:http://blog.163.com/lgh_2002/blog/static/4401752620105246517509/ http协议是WEB服务器与客户 端(浏览器)相互通信的协议,它是一种无状态协议。所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的。而越来越复杂的WEB 应用,需要保存一些用户状态信息。这时候,S...

php 保存编辑器内容中的远程图片为本地图片

有时,我们的编辑器复制过来的图片是远程的,需要下载到本地服务器上。 1、提取远程图片 /* *功能:php完美实现下载远程图片保存到本地 *参数:文件url,保存文件目录,保存文件名称,使用的下载方式 *当保存文件名称为空时则使用远程文件原来的名称 */ private function getImage($url,$filename='...

嵌入式web服务

:boa、thttpd、mini_httpd、shttpd、lighttpd、goaheand、appweb和apache等。 Boa 1.介绍 Boa诞生于1991年,作者Paul Philips。是开源的,应用很广泛,特别适合于嵌入式设备,网上流行程度很广。它的官方网站说boa是最受人喜爱的嵌入式web服务器。功能较为强大,支持认证,cgi等。B...

PHP模拟post提交数据方法汇总

使用php模拟post传值虽然在日常生活中用到的不是很多,但是在某些场合还是经常用到的。下面脚本之家小编给大家整理了三种php模拟post传值的方法,file_get_contents、curl和socket,需要的朋友参考下 第一种:file_get_contents来模拟post <php function file_get_contents...

PHP无法连接MYSQL8.0一般处理办法

以 mysql_native_password 加密方式修改密码 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; #更新一下用户的密码 FLUSH PRIVILEGES; #刷新权限 修改MYSQL.INI mysql8.0 默认用户加密...

CentOS 7编译安装Tengine+PHP+MariaDB全程笔记

  安装环境:CentOS7 3.10.0-693.5.2.el7.x86_64   准备源码包:     pcre-8.41.tar.gz     openssl-1.0.1h.tar.gz     zlib-1.2.11.tar.gz     jemalloc-4.5.0.tar.bz2     tengine-2.1.0.tar.gz     lib...