支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
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-command
。 LockHandler
在创建文件之前已经对字符串内容进行了过滤,以便你可以把任意值传入此参数。
.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 创作共用授权。