当前位置:首页 > Web开发 > 正文

test1和test2会顺序执行

2024-03-31 Web开发

今天在知乎浏览时忽然发明了一个有趣的对象,php竟然可以实现协程的实现,而且还是通过go关键字实现,马上觉得php此刻成长的好迅速,竟然把go里的对象都借鉴去。
只不过这是在一个叫Swoole的框架中实现的。
Swoole4为PHP语言供给了强大的CSP协程编程模式。底层供给了3个关键词,可以便利地实现种种成果。
Swoole4供给的PHP协程语法借鉴自Golang,在此向GO开发组致敬
PHP+Swoole协程可以与Golang很好地互补。Golang:静态语言,严谨强大性能好,PHP+Swoole:动态语言,灵活简单易用

关键词

go :创建一个协程

chan :创建一个通道

defer :延迟任务,在协程退出时执行,先进后出

这3个成果底层实现全部为内存操纵,没有任何IO资源消耗。就像PHP的Array一样长短常廉价的。如果有需要就可以直接使用。这与socket和file操纵差别,后者需要向操纵系统申请端口和文件描述符,读写可能会孕育产生梗阻的IO期待。

协程并发

function test1() { sleep(1); echo "b"; } function test2() { sleep(2); echo "c"; } test1(); test2();

执行功效:

bc real 0m3.080s user 0m0.016s sys 0m0.063s [email protected]-0K15EFQI:~$

上述代码中,test1和test2会挨次执行,需要3秒才华执行完成。

并发执行

使用go创建协程,可以让test1和test2两个函数酿成并发执行。

Swoole\Runtime::enableCoroutine(); go(function () { sleep(1); echo "b"; }); go(function () { sleep(2); echo "c"; });

Swoole\Runtime::enableCoroutine()感化是将PHP供给的stream、sleep、pdo、mysqli、redis等成果从同步梗阻切换为协程的异步IO

协程通信

有了go关键词之后,,并发编程就简单多了。与此同时又带来了新问题,如果有2个协程并发执行,此外一个协程,需要依赖这两个协程的执行功效,如果解决此问题呢?

答案就是使用通道(Channel),在Swoole4协程中使用new chan就可以创建一个通道。通道可以理解为自带协程调理的行列队伍。它有两个接口push和pop:

push:向通道中写入内容,如果已满,它会进入期待状态,有空间时自动恢复
pop:从通道中读取内容,如果为空,它会进入期待状态,有数据时自动恢复

使用通道可以很便利地实现并发打点

$chan = new chan(2); # 协程1 go (function () use ($chan) { $result = []; for ($i = 0; $i < 2; $i++) { $result += $chan->pop(); } var_dump($result); }); # 协程2 go(function () use ($chan) { $cli = new Swoole\Coroutine\Http\Client(, 80); $cli->set([timeout => 10]); $cli->setHeaders([ Host => "", "User-Agent" => Chrome/49.0.2587.3, Accept => text/html,application/xhtml+xml,application/xml, Accept-Encoding => gzip, ]); $ret = $cli->get(/); // $cli->body 响应内容过大,这里用 Http 状态码作为测试 $chan->push([ => $cli->statusCode]); }); # 协程3 go(function () use ($chan) { $cli = new Swoole\Coroutine\Http\Client(, 80); $cli->set([timeout => 10]); $cli->setHeaders([ Host => "", "User-Agent" => Chrome/49.0.2587.3, Accept => text/html,application/xhtml+xml,application/xml, Accept-Encoding => gzip, ]); $ret = $cli->get(/); // $cli->body 响应内容过大,这里用 Http 状态码作为测试 $chan->push([ => $cli->statusCode]); });

这里使用go创建了3个协程,协程2和协程3分袂请求qq.com和163.com主页。协程1需要拿到Http请求的功效。这里使用了chan来实现并发打点。

协程1循环两次对通道进行pop,因为行列队伍为空,它会进入期待状态

协程2和协程3执行完成后,会push数据,协程1拿到了功效,继续向下执行

Swoole4供给的Go + Chan + Defer为PHP带来了一种全新的CSP并发编程模式。灵活使用Swoole4供给的各项特性,可以解决事情中种种庞大成果的设计和开发。

php +go关键字实现协程

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/32000.html