Locker コルーチンロック
Locker は、コルーチン間の同期のためのメモリロックで、特定のクリティカルリソースへのアクセスを列に並ぶためによく使用されます。例えば、あるデータベースコンポーネントが接続プールを実装していない場合、Locker を利用してこのコンポーネントへのアクセスを順番待ちすることで、複数のコルーチンが同じ接続リソースを同時に使用してデータ異常が発生するのを防ぎます。
ヒント
この機能は workerman>=5.1.0 を必要とします。
注意
- Locker は Swoole/Swow/Fiber/Select/Event ドライバをサポートしています。
- Locker は同一プロセス内の異なるコルーチン間で、リソースへの排他的なアクセスを列に並ぶために使用され、プロセス間では互いに影響しません。
<?php
use Workerman\Connection\TcpConnection;
use Workerman\Coroutine\Locker;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8001');
$worker->eventLoop = Swoole::class; // または Swow::class または Fiber::class
$worker->onMessage = function (TcpConnection $connection, Request $request) {
static $redis;
if (!$redis) {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
}
// 複数のコルーチンが同じ接続を同時に使用するのを避け、「Socket#10 has already been bound to another coroutine」エラーを防ぎます
Locker::lock('redis');
$time = $redis->time();
Locker::unlock('redis');
$connection->send(json_encode($time));
};
Worker::runAll();
インターフェース説明
interface LockerInterface
{
/**
* ロックを取得
*/
public static function lock(string $key): bool
/**
* ロックを解放
*/
public static function unlock(string $key): bool
}