千家信息网

PHP协程中Go+Chan+Defer的示例分析

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要为大家展示了"PHP协程中Go+Chan+Defer的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"PHP协程中Go+Chan+Def
千家信息网最后更新 2025年02月01日PHP协程中Go+Chan+Defer的示例分析

这篇文章主要为大家展示了"PHP协程中Go+Chan+Defer的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"PHP协程中Go+Chan+Defer的示例分析"这篇文章吧。

Swoole4为PHP语言提供了强大的CSP协程编程模式。底层提供了3个关键词,可以方便地实现各类功能

Swoole4提供的PHP协程语法借鉴自Golang,在此向GO开发组致敬

PHP+Swoole协程可以与Golang很好地互补。Golang:静态语言,严谨强大性能好,PHP+Swoole:动态语言,灵活简单易用

关键词

  • go :创建一个协程

  • chan :创建一个通道

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

这3个功能底层实现全部为内存操作,没有任何IO资源消耗。就像PHP的Array一样是非常廉价的。如果有需要就可以直接使用。这与socket和file操作不同,后者需要向操作系统申请端口和文件描述符,读写可能会产生阻塞的IO等待。

协程并发

使用go函数可以让一个函数并发地去执行。在编程过程中,如果某一段逻辑可以并发执行,就可以将它放置到go协程中执行。

顺序执行

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

执行结果:

htf@LAPTOP-0K15EFQI:~$ time php b1.php  bc  real    0m3.080s  user    0m0.016s  sys     0m0.063s  htf@LAPTOP-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

执行结果:

bchtf@LAPTOP-0K15EFQI:~$ time php co.php  bc  real    0m2.076s  user    0m0.000s  sys     0m0.078s  htf@LAPTOP-0K15EFQI:~$

可以看到这里只用了2秒就执行完成了。

  • 顺序执行耗时等于所有任务执行耗时的总和 :t1+t2+t3...

  • 并发执行耗时等于所有任务执行耗时的***值 :max(t1, t2, t3, ...)

协程通信

有了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('www.qq.com', 80);         $cli->set(['timeout' => 10]);         $cli->setHeaders([         'Host' => "www.qq.com",         "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(['www.qq.com' => $cli->statusCode]);  });  # 协程3  go(function () use ($chan) {     $cli = new Swoole\Coroutine\Http\Client('www.163.com', 80);     $cli->set(['timeout' => 10]);     $cli->setHeaders([         'Host' => "www.163.com",         "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(['www.163.com' => $cli->statusCode]);  });

执行结果:

htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php co2.php  array(2) {    ["www.qq.com"]=>    int(302)    ["www.163.com"]=>    int(200) }  real    0m0.268s  user    0m0.016s  sys     0m0.109s  htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$

这里使用go创建了3个协程,协程2和协程3分别请求qq.com和163.com主页。协程1需要拿到Http请求的结果。这里使用了chan来实现并发管理。

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

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

延迟任务

在协程编程中,可能需要在协程退出时自动实行一些任务,做清理工作。类似于PHP的register_shutdown_function,在Swoole4中可以使用defer实现。

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

执行结果:

htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php defer.php  abc~b~a  real    0m1.068s  user    0m0.016s  sys     0m0.047s  htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$

以上是"PHP协程中Go+Chan+Defer的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

通道 内容 结果 任务 状态 示例 分析 两个 关键 关键词 函数 功能 篇文章 语言 顺序 编程 强大 底层 数据 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 手机老是显示已连接到服务器 证券公司服务器坏了 龙鼎网络技术有限公司 服务器开机后莫名打开好多端口 提高网络安全指标措施 服务器性能检测工具 打印机服务器软件 闻政绩效管理系统软件开发部 id软件开发工程师 珠海信息软件开发联系方式 加强学生网络安全教育教案 为什么要提高网络安全防护意识 app更新需要发布到服务器上吗 你碰到过哪些网络安全问题 软件开发启动资金 武穴实小网络安全宣传活动 数据库 当天时间 网络安全年龄问题 轻量分布式内存数据库 彩票选号软件开发 山东超频服务器咨询报价 国家网络安全宣传周天津公安 黑道总裁服务器维护 江苏省网络安全宣传周是 四川网络安全工程收费 怎么区分互联网和软件开发 杭州纵横网络技术 进入网络安全模式之后怎么办 今天服务器很卡用英文怎么说 数据库直接显示的语句
0