Swoole的Channel是协程间通信的同步数据结构,支持阻塞读写,适用于生产者-消费者模型;通过new SwooleCoroutineChannel(size)创建带缓冲的通道,生产者push数据,消费者pop获取,需注意关闭通道避免死锁。
Swoole 的 Channel 是一个用于协程间通信的同步数据结构,可以安全地在多个协程之间传递数据。它类似于 Go 语言中的 channel,支持阻塞读写操作,非常适合用于生产者-消费者模型。
创建 Channel
使用 SwooleCoroutineChannel 创建一个带缓冲区的通道,指定最大容量:
$channel = new SwooleCoroutineChannel(10); // 缓冲区最多存放10个元素
当通道满时,写入操作会阻塞;当通道为空时,读取操作会阻塞,直到有数据可用。
基本用法:生产者与消费者
下面是一个简单的例子,演示两个协程通过 Channel 通信:
use SwooleCoroutineChannel; use SwooleCoroutine; Coroutine::create(function () { $channel = new Channel(2); // 生产者协程 Coroutine::create(function () use ($channel) { echo "Producer: sending data 1n"; $channel->push("data 1"); echo "Producer: sending data 2n"; $channel->push("data 2"); $channel->close(); }); // 消费者协程 Coroutine::create(function () use ($channel) { echo "Consumer: waiting for data...n"; $data = $channel->pop(); echo "Consumer: received {$data}n"; $data = $channel->pop(); echo "Consumer: received {$data}n"; }); });
输出结果:
Consumer: waiting for data... Producer: sending data 1 Consumer: received data 1 Producer: sending data 2 Consumer: received data 2
应用场景与注意事项
Channel 常用于以下场景:
- 任务队列:生产者生成任务,消费者协程处理任务
- 限流控制:利用固定大小的 Channel 实现信号量机制
- 协程同步:等待某个事件完成
使用时注意:
- 记得调用 $channel->close() 避免消费者无限等待
- pop() 在 channel 关闭且无数据时返回 false
- 避免死锁:确保有协程读取,否则 push 可能永远阻塞
基本上就这些。Channel 是协程调度中非常实用的工具,合理使用能让程序逻辑更清晰。