From 71f729b0e2243fe853fe9fd8e9290f06541fe8ee Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Sat, 12 Jul 2025 18:25:34 +0800 Subject: [PATCH] add swoole coroutine lock --- reference/swoole/book.xml | 1 + reference/swoole/swoole.coroutine.lock.xml | 136 ++++++++++++++++++ .../swoole/coroutine/lock/construct.xml | 53 +++++++ .../swoole/swoole/coroutine/lock/lock.xml | 57 ++++++++ .../swoole/swoole/coroutine/lock/trylock.xml | 57 ++++++++ .../swoole/swoole/coroutine/lock/unlock.xml | 68 +++++++++ 6 files changed, 372 insertions(+) create mode 100644 reference/swoole/swoole.coroutine.lock.xml create mode 100644 reference/swoole/swoole/coroutine/lock/construct.xml create mode 100644 reference/swoole/swoole/coroutine/lock/lock.xml create mode 100644 reference/swoole/swoole/coroutine/lock/trylock.xml create mode 100644 reference/swoole/swoole/coroutine/lock/unlock.xml diff --git a/reference/swoole/book.xml b/reference/swoole/book.xml index c91dba43c695..511df0c76ec6 100644 --- a/reference/swoole/book.xml +++ b/reference/swoole/book.xml @@ -34,6 +34,7 @@ &reference.swoole.swoole.client; &reference.swoole.swoole.connection.iterator; &reference.swoole.swoole.coroutine; + &reference.swoole.swoole.coroutine.lock; diff --git a/reference/swoole/swoole.coroutine.lock.xml b/reference/swoole/swoole.coroutine.lock.xml new file mode 100644 index 000000000000..d536aeca854f --- /dev/null +++ b/reference/swoole/swoole.coroutine.lock.xml @@ -0,0 +1,136 @@ + + + + + + The Swoole\Coroutine\Lock class + Swoole\Coroutine\Lock + + + + +
+ &reftitle.intro; + + Swoole 6.0.1 introduced a coroutine lock that supports inter-process and inter-thread sharing. + This lock is designed with non-blocking behavior and enables efficient coroutine synchronization + in multi-process and multi-thread environments. + + + When compiled with the --enable-iouring option and the Linux kernel supports + the io_uring futex feature, Swoole's coroutine lock implements synchronization + using io_uring futex. In this case, coroutines wait for lock wakeups using + an efficient queuing mechanism, significantly improving performance. + + + Without io_uring futex, the coroutine lock falls back to an exponential backoff + sleep mechanism, where the wait time increases by 2^n milliseconds (n being the number of failures) + after each failed attempt to acquire the lock. While this approach avoids busy waiting, it introduces + additional CPU scheduling overhead and latency. + + + The coroutine lock is reentrant, allowing the currently holding coroutine to safely perform + multiple lock operations. + + + + Do not create locks in callback functions like onReceive, as this will cause + continuous memory growth and lead to memory leaks. + + + + + Locking and unlocking must be performed in the same coroutine, otherwise it will break + static conditions. + + +
+ + +
+ &reftitle.classsynopsis; + + + + Swoole\Coroutine\Lock + + + + + Swoole\Coroutine\Lock + + + + + &Methods; + + + + +
+ +
+ &reftitle.examples; + + Basic usage + +add(); + $lock->lock(); + sleep(1); + $lock->unlock(); + $waitGroup->done(); + }); + + go(function() use ($lock, $waitGroup) { + $waitGroup->add(); + $lock->lock(); // Wait for the holding coroutine to unlock + sleep(1); + $lock->unlock(); + $waitGroup->done(); + }); + + echo 'Lock does not block the process'; + $waitGroup->wait(); +}); +]]> + + +
+ +
+ + &reference.swoole.swoole.coroutine.entities.lock; +
+ + diff --git a/reference/swoole/swoole/coroutine/lock/construct.xml b/reference/swoole/swoole/coroutine/lock/construct.xml new file mode 100644 index 000000000000..183d75abeaff --- /dev/null +++ b/reference/swoole/swoole/coroutine/lock/construct.xml @@ -0,0 +1,53 @@ + + + + + + Swoole\Coroutine\Lock::__construct + Construct a new coroutine lock + + + + &reftitle.description; + + public voidSwoole\Coroutine\Lock::__construct + + + + Create a new coroutine lock instance. + + + + + &reftitle.parameters; + &no.function.parameters; + + + + &reftitle.returnvalues; + + void + + + + + diff --git a/reference/swoole/swoole/coroutine/lock/lock.xml b/reference/swoole/swoole/coroutine/lock/lock.xml new file mode 100644 index 000000000000..41421d671529 --- /dev/null +++ b/reference/swoole/swoole/coroutine/lock/lock.xml @@ -0,0 +1,57 @@ + + + + + + Swoole\Coroutine\Lock::lock + Acquire the lock, blocking if necessary + + + + &reftitle.description; + + public boolSwoole\Coroutine\Lock::lock + + + + When executing the lock operation, if the lock is already held by another coroutine, + the current coroutine will actively yield CPU control and enter a suspended state. + When the coroutine holding the lock calls unlock(), the waiting coroutine will be + awakened and try to acquire the lock again. + + + + + &reftitle.parameters; + &no.function.parameters; + + + + &reftitle.returnvalues; + + Returns true if the lock was acquired successfully, + false otherwise. + + + + + diff --git a/reference/swoole/swoole/coroutine/lock/trylock.xml b/reference/swoole/swoole/coroutine/lock/trylock.xml new file mode 100644 index 000000000000..19a75d354e8a --- /dev/null +++ b/reference/swoole/swoole/coroutine/lock/trylock.xml @@ -0,0 +1,57 @@ + + + + + + Swoole\Coroutine\Lock::trylock + Attempt to acquire the lock without blocking + + + + &reftitle.description; + + public boolSwoole\Coroutine\Lock::trylock + + + + When calling the lock operation, if the lock is already held by another coroutine, + the function will immediately return false without suspending the current coroutine + or yielding CPU control. This non-blocking design allows the caller to flexibly + handle contention situations, such as retrying, giving up, or executing other logic. + + + + + &reftitle.parameters; + &no.function.parameters; + + + + &reftitle.returnvalues; + + Returns true if the lock was acquired successfully, + false if the lock is not available. + + + + + diff --git a/reference/swoole/swoole/coroutine/lock/unlock.xml b/reference/swoole/swoole/coroutine/lock/unlock.xml new file mode 100644 index 000000000000..d9d69d377aff --- /dev/null +++ b/reference/swoole/swoole/coroutine/lock/unlock.xml @@ -0,0 +1,68 @@ + + + + + + Swoole\Coroutine\Lock::unlock + Release the lock + + + + &reftitle.description; + + public boolSwoole\Coroutine\Lock::unlock + + + + + + Unlock Behavior + + + + With io_uring futex: the system will precisely wake up one coroutine in the waiting queue. + + + + + Without io_uring futex: waiting coroutines need to wait for their backoff time to end + and compete to reacquire the lock. + + + + + + + &reftitle.parameters; + &no.function.parameters; + + + + &reftitle.returnvalues; + + Returns true if the lock was released successfully, + false otherwise. + + + + +