LockHandler

3.4 版本
维护中的版本

什么是锁定 

File locking文件锁定是一种架构,通过在任何特定时间点只允许一个用户或进程,来限制访问电脑上的文件。早在1963年这种架构就被引入,但在现代程序中却愈发有用。

Symfony提供了一个 LockHelper 来帮你在项目中使用锁定。

用法 

锁定仅工作在你使用一台服务器时。如果你有多个主机,不要使用这个helper。

锁定可以用于,比如,只允许运行命令行的一个实例:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Filesystem\LockHandler;
 
$lockHandler = new LockHandler('hello.lock');
if (!$lockHandler->lock()) {
    // the resource "hello" is already locked by another process
    // hello这个资源现已被另一个进程锁定
 
    return 0;
}

构造器的第一个参数是一个字符串,作为文件名称,用于在文件系统中创建一个锁定。对于Symfony命令行来说,最佳实践就是使用命令的名称(command name),比如 acme:my-commandLockHandler 在创建文件之前已经对字符串内容进行了过滤,以便你可以把任意值传入此参数。

.lock 扩展名是可选的,但在一般的实践中要把它包括进来。这可以令得在文件系统上找到锁定文件变得更容易。还有,要避免名称冲突,LockHandler 也加挂了一个hash到锁定文件的名称中。

默认时,锁定(文件)是被创建到临时文件中的,但你也可以可选地选择一个目录用于创建锁定,把它传入构造器的第二个参数即可。

lock() 方法尝试获取锁定。一旦获得,该方法返回 true,否则返回 false。如果 lock 方法在同一实例中被调用若干次,它将始终返回 true,如果第一次的调用获取到锁定的话。

你可以传入一个可选的blocking参数,作为 lock() 方法的第一个参数,默认是 false。如果设为 true,你的PHP代码将无限等待,直到锁定被另一进程所释放。

要留心一个事实,只要PHP对 LockHandler 对象应用了垃圾回收进程,资源的锁定就将自动释放。这意味着,如果你对本文第一个例子进行了如下重构:

1
2
3
4
5
6
7
8
use Symfony\Component\Filesystem\LockHandler;
 
 if (!(new LockHandler('hello.lock'))->lock()) {
    // the resource "hello" is already locked by another process
    // hello这个资源现已被另一个进程锁定
 
    return 0;
}

现在的代码将不会按预期工作,因为PHP的garbage collection机制删除了 LockHandler 对象的引用(reference),进而,锁定在它被创建之后即被释放。

另一种显式地释放锁定的方式,是在需要时使用release() 方法。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)