php的咨询文件锁定:flock

最近在研究php,碰到了一个问题,我使用如下代码锁定一个文件句柄

<?php
$filename = "/tmp/lock.txt";

$fp = fopen($filename, "r+");
if (!$fp) {
    die("open failed.");
}

if (flock($fp, LOCK_EX)) {  // 进行排它型锁定
    sleep(20);
    $count = (int)fgets($fp);
    $count += 1;
    fseek($fp, 0);
    fwrite($fp, (string)$count);
    fflush($fp);            // flush output before releasing the lock
    flock($fp, LOCK_UN);    // 释放锁定
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);
?>

访问,然后在sleep的20秒内尝试使用vi编辑/tmp/lock.txt,发现可以成功修改文件内容而不需要等待第一个脚本结束。经琢磨文档,发现这里有个概念叫" 咨询文件锁定",就是说所有访问程序必须使用同一方式锁定才会生效, 否则它不会工作。

尝试使用如下代码在20秒内访问:

<?php
$filename = "/tmp/lock.txt";

$fp = fopen($filename, "r+");
if (!$fp) {
    die("open failed.");
}

if (flock($fp, LOCK_EX)) {  // 进行排它型锁定
    $count = (int)fgets($fp);
    echo $count;
    $count += 1;
    flock($fp, LOCK_UN);    // 释放锁定
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);
?>

发现阻塞成功(第二个脚本需要等待第一个脚本结束才能继续运行)。

那么,什么叫同一种方式锁定呢?继续做如下实验:

A组:

  1. 尝试脚本1的flock参数修改为LOCK_SH,脚本2不变,试验,发现阻塞成功;(因为2要独占,要等共享锁结束)
  2. 尝试脚本1和脚本2的flock参数都修改为LOCK_SH,发现脚本2会可以返回结果而不用等待脚本1执行结束;(都是共享,无所谓了)


B组:

  1. 尝试将脚本2的flock参数修改为LOCK_SH,脚本1不变。阻塞成功。(因为被1独占了)


对照组:

  1. 尝试将脚本2的fopen参数修改为"r",运行A组实验,现象一样;(和打开文件的参数无关)
  2. 尝试将脚本1和2的fopen参数都修改为"w+",运行A组实验,现象一样;
  3. 尝试将脚本1和2的fopen参数都修改为"w+",运行B组实验,现象一样;


所以,锁定和LOCK_*参数相关。和打开文件的方式无关。而vi可以编辑的问题,是因为这个锁是线程级别的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值