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
}