PHP-PHP5.3 flock() 在chrome不同标签下无法实现非阻塞的问题?

PHP-PHP5.3 flock() 在chrome不同标签下无法实现非阻塞的问题?

浮生未歇 发布于 2017-08-31 字数 3524 浏览 1034 回复 1

我想实现的是:
当一个请求获得锁后并解锁之前,其他请求尝试获得锁失败后会直接返回,而不是阻塞!
阻塞设置在flock函数手册中有明显提到。

经过测试发现奇怪的问题:
在Firefox下,不同的标签进行测试,完全没问题!在IE8下测试也完全没有问题!
跨不同的浏览器进行测试,完全没有问题!

问题在于:chrome的两个标签下进行测试,会出现阻塞问题,我拿opera测试也是会出现阻塞!

我猜这是浏览器内部机制的问题,有谁能提供一个chrome下的解决方案?感激不尽!

<?php
/**
* CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库
* 用于解决PHP在并发时候的锁控制,通过文件/eaccelerator进行进程间锁定
* 如果没有使用eaccelerator则进行进行文件锁处理,会做对应目录下产生对应粒度的锁
* 使用了eaccelerator则在内存中处理,性能相对较高
* 不同的锁之间并行执行,类似mysql innodb的行级锁
* 本类在sunli的phplock的基础上做了少许修改 http://code.google.com/p/phplock
* @author yangxinqi
*
*/
class CacheLock
{
//文件锁存放路径
private $path = null;
//文件句柄
private $fp = null;
//锁粒度,设置越大粒度越小
private $hashNum = 100;
//cache key
private $name;
//是否存在eaccelerator标志
private $eAccelerator = false;

/**
* 构造函数
* 传入锁的存放路径,及cache key的名称,这样可以进行并发
* @param string $path 锁的存放目录,以"/"结尾
* @param string $name cache key
*/
public function __construct($name,$path='lock\')
{
//判断是否存在eAccelerator,这里启用了eAccelerator之后可以进行内存锁提高效率
$this->eAccelerator = function_exists("eaccelerator_lock");
if(!$this->eAccelerator)
{
$this->path = $path.($this->_mycrc32($name) % $this->hashNum).'.txt';
}
$this->name = $name;
}

/**
* crc32
* crc32封装
* @param int $string
* @return int
*/
private function _mycrc32($string)
{
$crc = abs (crc32($string));
if ($crc & 0x80000000) {
$crc ^= 0xffffffff;
$crc += 1;
}
return $crc;
}
/**
* 加锁
* Enter description here ...
*/
public function lock()
{
//如果无法开启ea内存锁,则开启文件锁
if(!$this->eAccelerator)
{
//配置目录权限可写
$this->fp = fopen($this->path, 'w+');
if($this->fp === false)
{
return false;
}
return flock($this->fp, LOCK_EX|LOCK_NB);
}else{
return eaccelerator_lock($this->name);
}
}

/**
* 解锁
* Enter description here ...
*/
public function unlock()
{
if(!$this->eAccelerator)
{
if($this->fp !== false)
{
flock($this->fp, LOCK_UN);
clearstatcache();
}
//进行关闭
fclose($this->fp);
}else{
return eaccelerator_unlock($this->name);
}
}
}

$lock = new CacheLock('key_name','./');
if($lock->lock()){
echo 'OK';
sleep(5);
$lock->unlock();
}else{
echo 'can't do anything!';
}

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏爱自由 2017-09-20 1 楼

chrome和firefox在多tab同时请求一个url时是会串行化运行的,鸟哥的博客原来说到过,具体原因貌似也没给出来。。。
http://www.laruence.com/2011/07/16/2123.html

这个应该是单个浏览器运行可能出现的问题,我想真实的并发环境中应该会达到你需要的那个效果