Swoole从入门到入土(26)——多进程[进程间锁]
多进程在Swoole中是一个很重要的话题,即是协程机制也是依赖于进程。所以Swoole\Lock让大家在PHP 代码中可以很方便地创建一个锁,用来实现数据同步。Lock 类支持以下 5 种锁的类型:
示例:
$lock = new Swoole\Lock(SWOOLE_MUTEX); echo "[Master]create lock\n"; $lock->lock(); if (pcntl_fork() > 0) { sleep(1); $lock->unlock(); } else { echo "[Child] Wait Lock\n"; $lock->lock(); echo "[Child] Get Lock\n"; $lock->unlock(); exit("[Child] exit\n"); } echo "[Master]release lock\n"; unset($lock); sleep(1); echo "[Master]exit\n";
注意:
- 请勿在 onReceive 等回调函数中创建锁,否则内存会持续增长,造成内存泄漏。
- 在协程中无法使用锁,请谨慎使用,不要在 lock 和 unlock 操作中间使用可能引起协程切换的 API。
成员函数
1) __construct():构造函数
Swoole\Lock::__construct(int $type = SWOOLE_MUTEX, string $lockfile = '');
$type:锁的类型
$lockfile:指定文件锁的路径【当类型为 SWOOLE_FILELOCK 时必须传入】(博主注:就文档所示,FILELOCK已经被废弃,这个参数相当于没用了)
注意:
- 不要循环创建 / 销毁锁的对象,否则会发生内存泄漏。
- 每一种类型的锁支持的方法都不一样。如读写锁、文件锁可以支持 $lock->lock_read()。另外除文件锁外,其他类型的锁必须在父进程内创建,这样 fork 出的子进程之间才可以互相争抢锁。
2) lock():加锁操作。如果有其他进程持有锁,那这里将进入阻塞,直到持有锁的进程 unlock() 释放锁。
Swoole\Lock->lock(): bool
3) locklock():加锁操作。与 lock 方法不同的是,trylock() 不会阻塞,它会立即返回。
woole\Lock->trylock(): bool
返回值:加锁成功返回 true,此时可以修改共享变量;加锁失败返回 false,表示有其他进程持有锁
注:SWOOlE_SEM 信号量没有 trylock 方法
4) unlock():释放锁
Swoole\Lock->unlock(): bool
5) lock_read():只读加锁
Swoole\Lock->lock_read(): bool
注意:
- 在持有读锁的过程中,其他进程依然可以获得读锁,可以继续发生读操作;
- 但不能 $lock->lock() 或 $lock->trylock(),这两个方法是获取独占锁,在独占锁加锁时,其他进程无法再进行任何加锁操作,包括读锁;
- 当另外一个进程获得了独占锁 (调用 $lock->lock()/$lock->trylock()) 时,$lock->lock_read() 会发生阻塞,直到持有独占锁的进程释放锁。
- 只有 SWOOLE_RWLOCK 和 SWOOLE_FILELOCK 类型的锁支持只读加锁
6) trylock_read():加锁。此方法与 lock_read() 相同,但是非阻塞的。
Swoole\Lock->trylock_read(): bool
注:调用会立即返回,必须检测返回值以确定是否拿到了锁。
7) lockwait():加锁操作。作用与 lock() 方法一致,但 lockwait() 可以设置超时时间。
Swoole\Lock->lockwait(float $timeout = 1.0): bool
$timeout:指定超时时间,单位:秒【支持浮点型,如 1.5 表示 1s+500ms】
返回值:在规定的时间内未获得锁,返回 false;加锁成功返回 true
注:只有 Mutex 类型的锁支持 lockwait
--------------------------- 我是可爱的分割线 ----------------------------
最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同学点击链接,联系我吧。