php 读锁,PHP 读文件怎么实现加锁

如@felix021 所说,flock($res, LOCK_EX|LOCK_NB) 是有效的,请好好看文档……

@卖掉内裤去上网 所说,memcached 虽然是纯内存操作,但毕竟有网络或unix domain socket开销,为了一个文件锁去启动一个Memcached未免太浪费。Linux中可以使用共享内存来做锁,请参考php手册中 shm_has_var / shm_put_var 。

如你自己说的,每进程分配一个专有文件也是可以的,并不是很麻烦,如果所有工作进程都有一个主进程fork出来就更方便了,最简单最dirty的办法是,把文件名放在主进程数组里,每次fork之前,就pop出来一个文件名……

用文件rename的方法跟@卖掉内裤去上网 说的依靠判断一个lock文件存在与否的办法开销差不多,如果你的文件数不是很多,锁抢占不频繁,可以这么做……

除了文件锁以外,其他自行实现的锁在有锁进程意外退出时,都需要自行实现解锁机制。所以,还是推荐用文件锁,会由系统来自动释放……

关于flock的演示function do_flock(){

ob_implicit_flush(true); //关闭PHP输出缓冲

$file = __FILE__;

$f = fopen($file, 'r');

$count = 0;

while(1){

$locked = flock($f, LOCK_NB | LOCK_EX);

if($locked) {

echo "GOT LOCK\n";

sleep(10);

flock($f, LOCK_UN);

echo "RELEASE LOCK\n";

break;

} else {

echo 'LOCKED BY OTHER, WAIT:' . ($count ++) . "\n";

sleep(1);

}

}

}

测试方法:time curl --no-buffer "http://localhost/flock"

//在10秒钟之内另外一个terminal里再执行相同命令

Terminal 1 输出:GOT LOCK

RELEASE LOCK

real0m10.023s

user0m0.008s

sys0m0.008s

Terminal 2 输出:LOCKED BY OTHER, WAIT:0

LOCKED BY OTHER, WAIT:1

LOCKED BY OTHER, WAIT:2

LOCKED BY OTHER, WAIT:3

LOCKED BY OTHER, WAIT:4

LOCKED BY OTHER, WAIT:5

LOCKED BY OTHER, WAIT:6

LOCKED BY OTHER, WAIT:7

LOCKED BY OTHER, WAIT:8

GOT LOCK

RELEASE LOCK

real0m19.025s

user0m0.008s

sys0m0.008s

Ubuntu 12.04 测试通过,没有Mac没法测,但应该没啥问题,毕竟是同根同源的,PHP源码里也只是对Win有特殊实现……

注意,以下情况会影响输出效果浏览器有渲染缓冲,webkit核心的浏览器大概需要额外输出4k字节的空白才会开始渲染输出

如果用FastCGI方式部署的PHP,Web服务器可能会有输出缓冲,我用的Cherokee大概也是4k左右的缓冲

针对这些缓冲,可以在每次echo时,把内容用str_pad补齐4096字节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值