petrknap / critical-section
基于 `symfony/lock` 的临界区
v2.1.0
2024-06-29 17:35 UTC
Requires
- php: >=8.1
- petrknap/shorts: ^2.1
- symfony/lock: ^6.0|^7.0
Requires (Dev)
- nunomaduro/phpinsights: ^2.11
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6
- squizlabs/php_codesniffer: ^3.7
README
The CriticalSection
是一个简单对象,为您处理临界区的开销,并让您专注于实际代码。
use PetrKnap\CriticalSection\CriticalSection; use Symfony\Component\Lock\NoLock; $lock = new NoLock(); $criticalOutput = CriticalSection::withLock($lock)(fn () => 'This was critical.'); var_dump($criticalOutput);
您可以通过 the WrappingCriticalSection
将临界区一层层包裹起来。这使得结合多个锁变得容易,例如。
use PetrKnap\CriticalSection\CriticalSection; use Symfony\Component\Lock\NoLock; $lockA = new NoLock(); $lockB = new NoLock(); $criticalOutput = CriticalSection::withLock($lockA)->withLock($lockB)(fn () => 'This was critical.'); var_dump($criticalOutput);
您还可以将锁作为数组传递,将组合留给临界区。
use PetrKnap\CriticalSection\CriticalSection; use Symfony\Component\Lock\NoLock; $lockA = new NoLock(); $lockB = new NoLock(); $criticalOutput = CriticalSection::withLocks([$lockA, $lockB])(fn () => 'This was critical.'); var_dump($criticalOutput);
您需要只接受已锁定的资源吗?
如果您需要确保您不在临界区外处理资源,请使用 the LockedResource
。
namespace PetrKnap\CriticalSection; use Symfony\Component\Lock\NoLock; /** @param Locked<Some\Resource> $resource */ function f(LockedResource $resource) { echo $resource->value; } $lock = new NoLock(); $resource = LockableResource::of(new Some\Resource('data'), $lock); CriticalSection::withLock($lock)(fn () => f($resource));
您的临界区与数据库兼容吗?
使用 the doctrine/dbal
及其 transactional
方法。
/** @var PetrKnap\CriticalSection\CriticalSectionInterface $criticalSection */ /** @var Doctrine\DBAL\Connection $connection */ $criticalSection( fn () => $connection->transactional( fn () => 'This was critical on DB server.' ) );
始终在临界区内使用 transactional
以防止饥饿。
运行 composer require petrknap/critical-section
来安装它。您可以通过 捐赠 支持此项目。该项目根据 the terms of the LGPL-3.0-or-later
许可。