• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

php文件锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前言

1、锁机制之所以存在是因为并发问题导致的资源竞争,为了确保操作的有效性和完整性,可以通过锁机制将并发状态转换成串行状态。作为锁机制中的一种,PHP 的文件锁也是为了应对资源竞争。假设一个应用场景,在存在较大并发的情况下,通过fwrite向文件尾部多次有序的写入数据,不加锁的情况下会发生什么? 多次有序的写入操作相当于一个事务,我们此时需要保证这个事务的完整性。 
2、例如:同时执行下面两段代码,会发现虽然都写入了数据,但是是两段程序交错写入,很明显这并不是期望的结果。

public function demo50() {
    $num = 10;
    $filename = 'process.txt';
    if ($fp = fopen($filename, 'a')) {
        for ($i = 0; $i<= $num; $i++) {
            fwrite($fp, 'process1:' . $i . "\r\n");
            usleep(100000);
        }
        fclose($fp);
    } else {
        echo 'faile';
    }
}

  

public function demo51() {
    $num = 10;
    $filename = 'process.txt';
    if ($fp = fopen($filename, 'a')) {
        for ($i = 0; $i<= $num; $i++) {
            fwrite($fp, 'process2:' . $i . "\r\n");
            usleep(100000);
        }
        fclose($fp);
    } else {
        echo 'faile';
    }
}

  

public function demo53() {
    // 创建一对cURL资源
    $ch1 = curl_init();
    $ch2 = curl_init();

    // 设置URL和相应的选项
    curl_setopt($ch1, CURLOPT_URL, "http://local.thinkphp.com/index.php?h=home&c=index&a=demo50");
    curl_setopt($ch2, CURLOPT_URL, "http://local.thinkphp.com/index.php?h=home&c=index&a=demo51");

    // 创建批处理cURL句柄
    $mh = curl_multi_init();

    // 增加2个句柄
    curl_multi_add_handle($mh, $ch1);
    curl_multi_add_handle($mh, $ch2);

    $running = null;
    // 执行批处理句柄
    do {
        curl_multi_exec($mh, $running);
    } while ($running > 0);

    // 关闭全部句柄
    curl_multi_remove_handle($mh, $ch1);
    curl_multi_remove_handle($mh, $ch2);
    curl_multi_close($mh);
}

  

运行结果如下


加上文件锁后

public function demo50() {
    $num = 10;
    $filename = 'process.txt';
    if ($fp = fopen($filename, 'a')) {
        if (flock($fp, LOCK_EX)) {
            for ($i = 0; $i<= $num; $i++) {
                fwrite($fp, 'process1:' . $i . "\r\n");
                usleep(100000);
            }
            flock($fp, LOCK_UN);
        }
        fclose($fp);
    } else {
        echo 'faile';
    }
}

  

public function demo51() {
    $num = 10;
    $filename = 'process.txt';
    if ($fp = fopen($filename, 'a')) {
        if (flock($fp, LOCK_EX)) {
            for ($i = 0; $i<= $num; $i++) {
                fwrite($fp, 'process2:' . $i . "\r\n");
                usleep(100000);
            }
            flock($fp, LOCK_UN);
        }
        fclose($fp);
    } else {
        echo 'faile';
    }
}

  

PHP文件锁:

  摘自:http://www.cnblogs.com/ninelands/archive/2012/09/18/2690713.html

1、文件锁有两种:共享锁和排它锁,也就是读锁(LOCK_SH)和写锁(LOCK_EX); 
2、但是什么时候使用LOCK_SH什么时候使用LOCK_EX呢? 
读的时候: 
如果不想出现dirty数据,那么最好使用lock_sh共享锁。可以考虑以下三种情况:

  1. 如果读的时候没有加共享锁,那么其他程序要写的话(不管这个写是加锁还是不加锁)都会立即写成功。如果正好读了一半,然后被其他程序给写了,那么读的后一半就有可能跟前一半对不上(前一半是修改前的,后一半是修改后的)
  2. 如果读的时候加上了共享锁(因为只是读,没有必要使用排他锁),这个时候,其他程序开始写,这个写程序没有使用锁,那么写程序会直接修改这个文件,也会导致前面一样的问题
  3. 最理想的情况是,读的时候加锁(lock_sh),写的时候也进行加锁(lock_ex),这样写程序会等着读程序完成之后才进行操作,而不会出现贸然操作的情况

写的时候: 
如果多个写程序不加锁同时对文件进行操作,那么最后的数据有可能一部分是a程序写的,一部分是b程序写的 
如果写的时候加锁了,这个时候有其他的程序来读,那么他会读到什么东西呢?

  1. 如果读程序没有申请共享锁,那么他会读到dirty的数据。比如写程序要写a,b,c三部分,写完a,这时候读读到的是a,继续写b,这时候读读到的是ab,然后写c,这时候读到的是abc.
  2. 如果读程序在之前申请了共享锁,那么读程序会等写程序将abc写完并释放锁之后才进行读。

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
PHP隐形一句话后门,和ThinkPHP框架加密码程序发布时间:2022-07-10
下一篇:
PHP中面相对象对象的知识点整理发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap