texthtml/php-lock

v2.2.1 2017-07-09 17:02 UTC

This package is auto-updated.

Last update: 2024-09-24 19:30:39 UTC


README

Build Status Latest Stable Version License Total Downloads Scrutinizer Code Quality

php-lock 是一个库,使得资源锁定变得简单。它可以用来避免在写操作期间访问文件,或者防止 crontab 任务的冲突。并且它被设计成可以很好地与依赖注入(例如 Symfony 容器或 Pimple)集成。

安装

使用 Composer

composer require texthtml/php-lock

使用方法

您可以创建一个表示文件锁的对象。然后您可以尝试通过调用 $lock->acquire() 来获取该锁。如果锁定失败,它将抛出 \TH\Lock\Exception(对于使用 Symfony Console 组件文档 构建的 CLI 工具很有用)。如果成功获取锁,程序可以继续运行。

独占锁定文件

use TH\Lock\FileLock;

$lock = new FileLock('/path/to/file');

$lock->acquire();

// other processes that try to acquire a lock on the file will fail

// edit /path/to/file

$lock->release();

// other processes can now acquire a lock on the file

共享文件锁

use TH\Lock\FileLock;

$lock = new FileLock('/path/to/file', FileLock::SHARED);

$lock->acquire();

// other processes that try to acquire an exclusive lock on the file will fail,
// processes that try to acquire an shared lock on the file will succeed

// read /path/to/file

$lock->release();

// other processes can now acquire an exclusive lock on the file if no other shared lock remains.

自动释放

$lock->release() 会在销毁锁时自动调用,所以您不需要在脚本结束时或当它超出作用域时手动释放它。

use TH\Lock\FileLock;

function batch() {
    $lock = new FileLock('/some/file');
    $lock->acquire();

    // lot of editing on file
}

batch();

// the lock will be released here even if $lock->release() is not called in batch()

使用锁进行 crontabs

当您不想某些 crontab 任务重叠时,可以在每个 crontab 中对同一文件进行锁定。TH\Lock\LockFactory 可以简化此过程,并在发生冲突时提供更多有用的信息。

$lock = $factory->create('protected resource', 'process 1');

$lock->acquire();

// process 1 does stuff
$lock = $factory->create('protected resource', 'process 2');

$lock->acquire();

// process 2 does stuff

当进程 1 正在运行时,我们启动进程 2,将抛出异常:"无法获取受保护资源的独占锁",如果工厂配置了 \Psr\Log\LoggerInterface,则会在日志中记录解释发生情况的语句。

process 1: exclusive lock acquired on protected resource
process 2: could not acquire exclusive lock on protected resource
process 2: lock released on protected resource

目前可用的唯一 LockFactoryTH\Lock\FileFactory。该工厂将自动在指定的文件夹中为您的资源创建锁文件。

use TH\Lock\FileFactory;

$factory = new FileFactory('/path/to/lock_dir/');
$lock = $factory->create('resource identifier');

聚合锁

如果您想简化同时获取多个锁,可以使用 \TH\Lock\LockSet

use TH\Lock\LockSet;

$superLock = new LockSet([$lock1, $lock2, $lock3]);
// You can make a set with any types of locks (eg: FileLock, RedisSimpleLock or another nested LockSet)

$superLock->acquire();

// all locks will be released when $superLock is destroyed or when `$superLock->release()` is called

它将尝试获取所有锁,如果失败,则释放已获取的锁,以避免锁定其他进程。

注意:将 Lock 放入 LockSet 中后,不应再手动使用

注意

分布式系统

在分布式系统中,基于文件的锁定不起作用,您可以使用 php-lock redis 扩展 来获得安全的锁。