- 本文地址: https://www.yangdx.com/2019/02/15.html
- 转载请注明出处
思路其实很简单:用fopen打开一个文件,然后用flock获取该文件的独占锁,当前脚本还没跑完时,会一直持有这个锁,另一个脚本尝试获取锁就会返回失败并退出,从而达到控制同一时间只有一个脚本实例在执行的效果。
封装代码如下:
/**
* 获取文件锁
* 一般用于命令行脚本的单例模式
*/
class FileLock {
/**
* 文件句柄
* @var resource
*/
private $fp = null;
/**
* 文件路径
* @var string
*/
private $filePath = '';
/**
* 构造函数
* @param string $filename 文件名称
*/
public function __construct($filename) {
$tempDir = sys_get_temp_dir();
$this->filePath = $tempDir . DIRECTORY_SEPARATOR . $filename;
}
/**
* 取得文件独占锁
*/
public function lock() {
$this->fp = fopen($this->filePath, 'a+');
if (!flock($this->fp, LOCK_EX | LOCK_NB, $wouldblock)) {
if ($wouldblock) {
throw new Exception("另一个进程已持有文件锁");
} else {
throw new Exception("获取文件锁失败");
}
}
}
/**
* 释放文件锁
*/
public function unlock() {
flock($this->fp, LOCK_UN);
}
/**
* 析构函数
*/
public function __destruct() {
fclose($this->fp);
}
}
运用举例:
if (PHP_SAPI != 'cli') {
exit("请在命令行模式下执行\n");
}
try {
$fl = new FileLock('testfile.lock');
$fl->lock();
//您的业务代码
echo "业务执行中...\n";
sleep(10);
echo "执行完毕。\n";
$fl->unlock();
} catch (Exception $ex) {
$msg = $ex->getMessage();
echo $msg . "\n";
exit;
}
unlock不是必须的,因为php有垃圾回收机制,使得脚本在执行结束后会自动释放锁。
快来评论一下吧!
发表评论