1.前言
swoole从4.X版本后开始完整的支持协程的编程,swoole中的协程实质是单线程同步模式,创建新协程后,当协程挂起或者执行结束会让出CPU控制权给父协程继续执行之后的代码。通过Co::sleep可以自动的让出会恢复协程,而Co::yield则是手动的让出协程,并且只能通过Co::resume恢复指定的协程。
2.协程的创建
协程的创建方式有3种:
1.Swoole\Coroutine::create(callable $function, …$args) //原生的创建API
2.go(callable $function, …$args)//短名API
3.原生的协程组件:
Swoole\Coroutine\Client
Swoole\Coroutine\HTTP\Client
Swoole\Coroutine\HTTP2\Client
Swoole\Coroutine\Redis
Swoole\Coroutine\MySQL
Swoole\Coroutine\PostgreSQL
Coroutine\Server
3.协程的执行顺序
<?php
$a = 1;
echo 'step3-cid:' . go(function() {
global $a;
echo 'step1:' . $a . PHP_EOL;
echo 'step2-cid:' . go(function () {
global $a;
++$a;
co::sleep(3.0);
echo 'step6-cid:' . go(function () {
global $a;
++$a;
co::sleep(2.0);
echo 'step8:' . PHP_EOL;
}) . PHP_EOL;
echo "step7:" . PHP_EOL;
}) . PHP_EOL;
co::sleep(1.0);
echo 'step5:' . $a . PHP_EOL;
}) . PHP_EOL;
echo 'step4:' . PHP_EOL;

4.协程通道的使用
通道(Channel)特性和进程间通信的管道类似,而其数据结构则和数组相似。当管道满的时候,push协程会让出CPU给pop协程,当管道为空时,则pop协程会让出CPU给push协程。
<?php
use Swoole\Coroutine as co;
$chan = new co\Channel(1);
co::create(function () use ($chan) {
for($i = 0; $i < 2; $i++) {
co::sleep(1.0);
echo 'start' . PHP_EOL;
$chan->push($i);
echo "$i\n";
}
});
co::create(function () use ($chan) {
while(1) {
echo 'handling' . PHP_EOL;
$data = $chan->pop();
var_dump($data);
}
});
go(function() use ($chan) {
$chan->push(['123']);
echo 'push' . PHP_EOL;
$chan->push(['321']);
});
5.协程客户端 setDefer 并发请求收包
协程客户端还支持并发请求,也就是发送异步请求。收包的时间为max(request_time_out),最长的请求时间。
$n = 5;
for ($i = 0; $i < $n; $i++) {
$cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 80);
$cli->setHeaders([
'Host' => "local.ad.oa.com",
"User-Agent" => 'Chrome/49.0.2587.3',
'Accept' => 'text/html,application/xhtml+xml,application/xml',
'Accept-Encoding' => 'gzip',
]);
$cli->set([ 'timeout' => 2]);
$cli->setDefer();
$cli->get('/test.php');
$clients[] = $cli;
}
for ($i = 0; $i < $n; $i++) {
$r = $clients [$i]->recv();
$result[] = $clients[$i]->body;
}
如无特殊说明,文章均为本站原创,转载请注明出处。如发现有什么不对的地方,希望得到您的指点。