社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
date: 2019-05-01 19:09:34
title: swoole| swoole 协程用法笔记
协程方法简明笔记:
Coroutine::set
协程设置
max_coroutine
Coroutine::stats
协程状态
Coroutine::list
遍历当前进程中的所有协程
Coroutine::getBackTrace
查看协程调用栈
Coroutine::listCoroutines()
Coroutine::create
创建协程
go()
Coroutine::defer
类似 go 的 defer, PHP 有析构函数(__destruct()
)和自动回收机制, defer 的使用范围没那么大
defer()
CoroutineChannel
类似 go 的 chan, 所有操作均为内存操作, 进程间内存隔离
chan()
空/满
会影响到后续的 push / popCoroutine::getCid
当前协程id, 即 cid
Coroutine::exist
Coroutine::getPcid
获取父协程cid
Coroutine::getContext
Coroutine::yield
让出当前协程的执行权, 需要配合 resume 使用, 由其他协程唤醒
Coroutine::suspend
Coroutine::resume
唤醒其他协程
Coroutine::exec
协程版 shell_exec()
Coroutine::gethostbyname
DNS查询, todo -> http client 是否需要
Coroutine::getaddrinfo
Coroutine::statvfs
获取文件系统信息(目前还不知道使用场景)
CoroutineClient
CoroutineHttpClient
CoroutineHttp2Client
CoroutineSocket
CoroutinePostgreSQL
--enable-coroutine-postgresql
开启协程 runtime 后(SwooleRuntime::enableCoroutine()
), 可以不再使用:
Coroutine::fread
Coroutine::fgets
Coroutine::fwrite
Coroutine::sleep
Coroutine::readFile
Coroutine::writeFile
CoroutineRedis
使用 ext-redis(phpredis) / predisCoroutineMySQL
使用 mysqlnd 模式的 pdo、mysqli 扩展swoole 中使用协程的 2 个要点:
go()
一下就行了go(function () {
sleep(1); // 未开启协程 runtime, 此处会阻塞, 输出为 go -> main
echo "go n";
});
echo "main n";
输出为: go -> main
SwooleRuntime::enableCoroutine();
go(function () {
sleep(1); // 开启协程 runtime, 此处为阻塞, 输出为 main -> go
echo "go n";
});
echo "main n";
输出为: main -> go
, 发生了协程调度.
使用时将 sleep(1)
替换为需要检测的代码即可.
SwooleCoroutine
命名空间保持一致性, 按需封装常用的几个, 比如 go() chan() defer()
if (! function_exists('go')) {
function go(callable $callable)
{
HyperfUtilsCoroutine::create($callable);
}
}
if (! function_exists('defer')) {
function defer(callable $callable): void
{
HyperfUtilsCoroutine::defer($callable);
}
}
max_coroutine
, 更科学方式(看是否有需要): 压测后查看内存占用, 进而进行调整__destruct()
官方提供了 2 种方式:
个人不建议使用, 并发调用可以达到更好的性能, 但是不符合常用的编程习惯, 多个请求需要同时完成, 推荐使用 waitGroup
, 在此基础上, 还可以封装成更简单的写法
class WaitGroup
{
/**
* @var int
*/
private $counter = 0;
/**
* @var SwooleChannel
*/
private $channel;
public function __construct()
{
$this->channel = new chan();
}
public function add(int $incr = 1): void
{
$this->counter += $incr;
}
public function done(): void
{
$this->channel->push(true);
}
public function wait(): void
{
while ($this->counter--) {
$this->channel->pop();
}
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!