rfc
rfc copied to clipboard
进程间协程锁
背景
目前,多进程
之间的协程同步只能通过Swoole\Lock
或者通过flock
函数对同一份文件加锁。Swoole\Lock
没法在协程中使用,会阻塞当前进程。flock
对文件加锁需要先打开文件,再对文件加锁。此时会发生两次协程切换。
协程锁
- 通过
io_uring
提供的异步futex
特性和sw_atomic_cmp_set
函数,可以实现一个无需加锁的原子计数,可重入的互斥锁。 - 进程间的各个协程只会有一个协程会获得锁,剩余的协程会发生一次协程切换让出各自的CPU,根据获取锁的顺序在内核中排队等待唤醒。
- 多线程模式下的
并发List
,并发Map
和并发Queue
在并发写入时是使用互斥锁来保证线程安全的,线程获取不到锁的过程中会休眠。那么可以尝试用协程锁控制并发。 - 协程锁只能在协程环境下使用。
API
- 在原本的
Swoole\Lock
做兼容,增加一个SWOOLE_COROUTINE_LOCK
。 - 只支持
Swoole\Lock->lock()
和Swoole\Lock->unlock()
,其他方法会返回false。
$lock = new Lock(SWOOLE_COROUTINE_LOCK);
$lock->lock();
$lock->unlock();
缺点
- 对linux内核要求较高,linux内核为6.7以上才支持。
- 需要io_uring支持。