欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP并发操作上的加锁

程序员文章站 2022-05-29 22:06:40
...
PHP并发操作下的加锁

php如何解决多线程读写同一文件

大家都知道,PHP是没有多线程概念的,尽管如此我们仍然可以用“不完美”的方法来模拟多线程。简单的说,就是队列处理。通过对文件进行加锁和解锁,来实 现。当一个文件被一个用户操作时,该文件是被锁定的,其他用户只能等待,确实不够完美,但是也可以满足一些要求不高的应用。

有这么一个需求:生成文件的时候,由于多用户都有权限进行生成,防止并发下,导致生成的结果出现错误,需要对生成的过程进行加锁,只容许一个用户在 一个时间内进行操作,这个时候就需要用到锁了,将这个操作过程锁起来。在用了cache的时候,cache失效可能导致瞬间的多数并发请求穿透到数据库此 时也可以得需要用锁在同一并发的过程中将这个操作锁定。

针对以上的2种情况,现在的解决方法是对处理过程进行锁机制,通过PHP实现如下:

用到了Eaccelerator的内存锁和文件锁,原理:判断系统中是否安了EAccelerator如果有则使用内存锁,如果不存在,则进行文件锁。根据带入的key的不同可以实现多个锁直接的并行处理,类似Innodb的行级锁。

具体类如下:

eAccelerator = function_exists("eaccelerator_lock");
		if(!$this->eAccelerator)
		{
			if (!is_dir($path)) {
				mkdir($path, 0777);
			}
			$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);
		}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');
$lock->lock();
//logic here
$lock->unlock();
//使用过程中需要注意下文件锁所在路径需要有写权限.
PHP并发操作上的加锁

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

相关文章

相关视频