Swoole锁使用疑问:仅SPINLOCK可用及读写锁操作咨询
Hey Davis, let's break down your two questions about Swoole locks based on my hands-on experience with the extension:
1. Why only SWOOLE_SPINLOCK can acquire locks, while others return false?
The most common reasons other lock types fail to acquire boil down to initialization mistakes or mismatched usage scenarios. Here's a breakdown of potential issues and fixes:
Incorrect lock initialization parameters:
For example:SWOOLE_FILELOCKrequires a valid, accessible file path (with read/write permissions). If the file doesn't exist or your process lacks permissions, the lock initialization will silently fail, leading tolock()returning false. Always check if the lock object was created properly, and use$lock->errCodeand$lock->errMsgto debug:$fileLock = new Swoole\Lock(SWOOLE_FILELOCK, '/tmp/swoole_file_lock.lock'); if (!$fileLock->lock()) { echo "Lock failed: Code {$fileLock->errCode}, Msg {$fileLock->errMsg}\n"; }SWOOLE_SEMneeds a unique system key and a valid count value. Using a duplicate key or a non-positive count will cause initialization failure.
Misunderstanding lock scope:
Most Swoole locks (except spinlock) are designed for inter-process or inter-thread synchronization. If you're testing them in a single-threaded, single-process environment without proper setup (like sharing the lock with child processes), you might encounter unexpected failures. For example,SWOOLE_MUTEXrequires the lock to be accessible across processes (via inheritance or shared memory) to work as intended.Lock already held elsewhere:
Unlike spinlock (which uses busy-waiting in user space), other locks will return false immediately if the lock is already held by another process/thread. Make sure no other process is holding the lock before attempting to acquire it.
2. How to perform lock acquisition and release for SWOOLE_RWLOCK (read-write lock)?
Swoole's read-write lock supports two modes: shared read locks (multiple readers can hold the lock at the same time) and exclusive write locks (only one writer can hold the lock, and no readers are allowed). Here's a practical example:
Basic Usage
// Initialize the read-write lock $rwLock = new Swoole\Lock(SWOOLE_RWLOCK); // Acquire a shared read lock if ($rwLock->lock(SWOOLE_RLOCK)) { echo "Successfully acquired read lock, performing read operations...\n"; // Your read logic here (e.g., reading shared data) sleep(2); // Simulate read work $rwLock->unlock(); // Release the read lock echo "Read lock released\n"; } // Acquire an exclusive write lock if ($rwLock->lock(SWOOLE_WLOCK)) { echo "Successfully acquired write lock, performing write operations...\n"; // Your write logic here (e.g., modifying shared data) sleep(2); // Simulate write work $rwLock->unlock(); // Release the write lock echo "Write lock released\n"; }
Multi-Process Scenario
To use the read-write lock across child processes, ensure the lock object is inherited by the child process:
$rwLock = new Swoole\Lock(SWOOLE_RWLOCK); // Create a child process to acquire read lock $readerProcess = new Swoole\Process(function ($process) use ($rwLock) { if ($rwLock->lock(SWOOLE_RLOCK)) { echo "Child reader: Acquired read lock\n"; sleep(3); $rwLock->unlock(); echo "Child reader: Released read lock\n"; } }); $readerProcess->start(); // Parent process acquires write lock after a delay sleep(1); if ($rwLock->lock(SWOOLE_WLOCK)) { echo "Parent writer: Acquired write lock\n"; $rwLock->unlock(); echo "Parent writer: Released write lock\n"; } Swoole\Process::wait();
Key Notes:
- Avoid deadlocks: Never attempt to acquire a write lock while holding a read lock (or vice versa) in the same process—this will cause a deadlock.
- Always unlock: Ensure every successful
lock()call has a correspondingunlock()to prevent resource leaks and deadlocks. - Reader-writer priority: Swoole's RWLock typically prioritizes writers, meaning pending write locks will block new read locks until the write operation is complete.
内容的提问来源于stack exchange,提问作者Davis.S

