PHP文件锁

共享锁

        测试方法,读取两次文件,中间增加延时,在延时的时候执行写入方法

方法:
/**
 * 读取文件内容
 */
protected function read()
{
    $lockFile = __DIR__.'/test.log';    // 文件地址

    $fp = fopen($lockFile, 'r');    // 打开文件

    dump(flock($fp, LOCK_SH));  // 加锁(共享锁)

    dump(fread($fp, 1024));  // 读取文件内容

    sleep(10);  // 增加延时,用于写入测试

    fseek($fp, 0);  // 将文件指针指向文件开头

    dump(fread($fp, 1024));  // 再次读取文件内容

    flock($fp, LOCK_UN);    // 释放锁

    fclose($fp);    // 关闭文件
}

/**
 * 写入文件内容(第一次,不用锁验证)
 */
protected function write()
{
    $lockFile = __DIR__.'/test.log';

    $fp = fopen($lockFile, 'r+');

    fwrite($fp, 'test:'.date('Y-m-d H:i:s').PHP_EOL);

    fclose($fp);
}

/**
 * 写入文件内容(第二次,用锁验证)
 */
protected function write2()
{
    $lockFile = __DIR__.'/test.log';

    $fp = fopen($lockFile, 'r+');

    if(!flock($fp, LOCK_EX)){
        echo '文件被锁定';
        fclose($fp);
        exit;
    }

    fwrite($fp, 'test:'.date('Y-m-d H:i:s'));

    fclose($fp);
}
测试文件初始内容:        
第一次测试结果:

        结果两次读取到的内容是不同的,此时看来共享锁是没有任何作用的。

第二次测试结果

        结果两次读取到的内容是相同的

注意:

        1、我在写入文件的时候用的r+,如果用w+的话,读取方法第二次读取到的内容会是个空,关于这个可以看看fopen函数的介绍。

        2、我在第二次的写入方法中flock是没有增加LOCK_NB所以写入方法不会进入if的判断。这个参数代表了flock如果发现文件被加锁了是否要等待执行,也就是flock的阻塞和非阻塞


独占锁

        独占锁就很好理解了,加锁后其他进程不允许读和写。

        测试方法和上面一样,将读取方法的LOCK_SH改为LOCK_EX

方法:
/**
 * 读取/写入文件
 */
protected function writeAndRead()
{
    $lockFile = __DIR__.'/test.log';

    $fp = fopen($lockFile, 'r+');

    dump(fwrite($fp, 'test:'.date('Y-m-d H:i:s')));    // 写入文件内容

    dump(fread($fp, 1024));  // 再次读取文件内容

    fclose($fp);
}

测试结果:

总结

        文件锁的锁和字面意思是不一样的,最初我理解为加锁后其他进程不能对文件进行相应操作。测试后发现这个锁相当于给文件增加了一个属性并赋值为已上锁,其他进程需要每次获取这个属性从而来确认文件是否可以操作。

        1、进程A增加共享锁,进程B增加共享锁,正常执行(共享锁可以增加多个)

        2、进程A增加共享锁,进程B增加独占锁,进程B阻塞等待进程A执行完成(增加了共享锁的文件不可以增加独占锁)

        3、进程A增加独占锁,进程B不论增加共享锁还是独占锁都是阻塞等待进程A执行完成

        4、如果不想让进程B阻塞,增加LOCK_NB

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值