请勿在onReceive等回调函数中创建锁,否则内存会持续增长,造成内存泄漏;协程中无法使用锁;不要在lock和unlock操作中间使用可能引起协程切换的API
$lock_types = [
SWOOLE_MUTEX, // 互斥锁
SWOOLE_RWLOCK, // 读写锁
SWOOLE_SPINLOCK, // 自旋锁
];
互斥锁
use Swoole\Process;
use Swoole\Lock;
// 创建锁
$lock = new Lock(SWOOLE_MUTEX);
$worker1 = new Process(function ($process) use ($lock) {
// 加锁,如果有其他进程持有锁,那这里将进入阻塞,直到持有锁的进程 unlock() 释放锁。获取独占锁,在独占锁加锁时,其他进程无法再进行任何加锁操作,包括读锁
if ($lock->lock()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
}
});
$worker1->start();
$worker2 = new Process(function ($process) use ($lock) {
if ($lock->lock()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
}
});
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
互斥锁超时
use Swoole\Process;
use Swoole\Lock;
// 创建锁
$lock = new Lock(SWOOLE_MUTEX);
$worker1 = new Process(function ($process) use ($lock) {
// 加锁并设置超时时间,获取独占锁,在独占锁加锁时,其他进程无法再进行任何加锁操作,包括读锁;只有SWOOLE_MUTEX类型可以使用
if ($lock->lockwait(2)) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "{$process->pid}:获取锁超时" . PHP_EOL;
}
});
$worker1->start();
$worker2 = new Process(function ($process) use ($lock) {
if ($lock->lockwait(2)) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "{$process->pid}:获取锁超时" . PHP_EOL;
}
});
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
互斥锁非阻塞
use Swoole\Process;
use Swoole\Lock;
// 创建锁
$lock = new Lock(SWOOLE_MUTEX);
$worker1 = new Process(function ($process) use ($lock) {
// 加锁但不阻塞,获取独占锁,在独占锁加锁时,其他进程无法再进行任何加锁操作,包括读锁
if ($lock->trylock()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "其他进程获得锁,{$process->pid}:获取不到" . PHP_EOL;
}
});
$worker1->start();
$worker2 = new Process(function ($process) use ($lock) {
if ($lock->trylock()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "其他进程获得锁,{$process->pid}:获取不到" . PHP_EOL;
}
});
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
读写锁-只读锁
use Swoole\Process;
use Swoole\Lock;
// 创建锁
$lock = new Lock(SWOOLE_MUTEX);
$worker1 = new Process(function ($process) use ($lock) {
// 加只读锁;在持有读锁的过程中,其他进程依然可以获得读锁,可以继续发生读操作;只有SWOOLE_RWLOCK类型可以使用
if ($lock->lock_read()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
}
});
$worker1->start();
$worker2 = new Process(function ($process) use ($lock) {
if ($lock->lock_read()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
}
});
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
读写锁-只读锁-非阻塞
use Swoole\Process;
use Swoole\Lock;
// 创建锁
$lock = new Lock(SWOOLE_MUTEX);
$worker1 = new Process(function ($process) use ($lock) {
// 加只读锁但不阻塞,在持有读锁的过程中,其他进程依然可以获得读锁,可以继续发生读操作
if ($lock->trylock_read()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "其他进程获得锁,{$process->pid}:获取不到" . PHP_EOL;
}
});
$worker1->start();
$worker2 = new Process(function ($process) use ($lock) {
if ($lock->trylock_read()) {
echo "{$process->pid}:锁" . PHP_EOL;
sleep(3);
// 释放锁
$lock->unlock();
echo "{$process->pid}:释放" . PHP_EOL;
} else {
echo "其他进程获得锁,{$process->pid}:获取不到" . PHP_EOL;
}
});
$worker2->start();
while ($status = Process::wait(true)) {
echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}