swoole4.0协程初探

2018年11月29日 205点热度 0人点赞 0条评论

swoole4.0可使用协程+通道的全新编程模式,代替异步回调,应用层可使用完全同步的编程方式,底层自动实现异步I/O


下面会通过一段代码,来帮助大家理解swoole的协程

<?php
use Swoole\Coroutine\Http\Client;
//此方法记录执行时间
function timediff($time)
{
return microtime(true) - $time;
}

//创建http server
$http = new Swoole\Http\Server("0.0.0.0", 9501);
$http->set([
//"daemonize" => true,
   "worker_num" => 1,
]);
$http->on('request', function ($request, $response) {

//浏览器会自动发起这个请求,这也是很多人碰到的一个问题:
   //为什么我浏览器打开网站,收到了两个请求?
   if ($request->server['path_info'] == '/favicon.ico') {
$response->end('');
return;
}

$time = microtime(true);
$response->header("content-type", "text/html; charset=UTF-8");
$response->write("1. 接受请求,此处被执行, 第" . __LINE__ . "行, 时间" . $time . "<br/>");

//启动第一个协程
   go(function () use ($response) {
$time = microtime(true);
$response->write("2. 进入第一个协程,发起http请求taobao, 第" . __LINE__ . "行, 时间:" . $time . "<br/>");

//启动一个协程客户端client,请求淘宝首页
       $cli = new Client('www.taobao.com', 443, true);
$cli->setHeaders([
'Host' => "www.taobao.com",
"User-Agent" => 'Chrome/49.0.2587.3',
'Accept' => 'text/html,application/xhtml+xml,application/xml',
'Accept-Encoding' => 'gzip',
]);
$cli->set(['timeout' => 1]);
//调用get方法,协程挂起,
       $cli->get('/index.php');
//会等待i/o数据返回,才会继续执行下面
       $response->write("7. get回taobao数据,唤起协程,此处被执行, 第" . __LINE__ . "行, 执行时间" . timediff($time) . "<br/>");
$cli->close();
});
//上面get挂起协程后,后立马执行这一行
   $response->write("3 cli->get时挂起协程了,此处被执行,不会被阻塞, 第" . __LINE__ . "行, 时间:" . microtime(true) . "<br/>");

//启动第二个协程
   go(function () use ($response) {
$time = microtime(true);
$response->write("4. 进入第二个协程,发起http请求baidu, 第" . __LINE__ . "行, 时间:" . $time . "<br/>");
//启动一个协程客户端client,请求百度首页
       $cli = new Client('www.baidu.com', 443, true);
$cli->setHeaders([
'Host' => "www.baidu.com",
"User-Agent" => 'Chrome/49.0.2587.3',
'Accept' => 'text/html,application/xhtml+xml,application/xml',
'Accept-Encoding' => 'gzip',
]);
$cli->set(['timeout' => 1]);
//调用get方法,协程挂起,
       $cli->get('/index.php');
//会等待i/o数据返回,才会继续执行下面
       $response->write("6. get回baidu数据,唤起协程,此处被执行,正常这个先返回,因为ping百度更快,说明两个协程也是并发执行的, 第" . __LINE__ . "行, 执行时间" . timediff($time) . "<br/>");
$cli->close();
});
//第二个协程get时挂起,执行到这一步
   $response->write("5 cli->get时挂起协程了,此处被执行,不会被阻塞, 第" . __LINE__ . "行, 时间:" . microtime(true) . "<br/>");
});
$http->start();

运行
1、保存为http.php

2、执行  php http.php
3、浏览器打开:http://127.0.0.1:9501/

几个关键点:

Swoole的协程是单进程的

代码遇到i/o操作会挂起协程

协程之间是并发的,相互不堵塞

预告:下一篇用代码实现类似golang的waitgroup功能

PHP饭米粒(phpfamily) 由一群靠谱的人建立,愿为PHPer带来一些值得细细品味的精神食粮!

饭米粒只发原创或授权发表的文章,不转载网上的文章

所发的文章,均可找到原作者进行沟通。

也希望各位多多打赏(算作稿费给文章作者),更希望大家多多投搞。

投稿请联系:

[email protected]


本文由 半桶水 授权 饭米粒 发布,转载请注明本来源信息和以下的二维码(长按可识别二维码关注)

图片

34570swoole4.0协程初探

这个人很懒,什么都没留下

文章评论