协程:实现 sync.WaitGroup 功能

Swoole4中可以使用channel实现协程间的通信、依赖管理、协程同步。基于channel可以很容易地实现Golangsync.WaitGrup功能。

实现代码

  1. class WaitGroup
  2. {
  3. private $count = 0;
  4. private $chan;
  5. /**
  6. * waitgroup constructor.
  7. * @desc 初始化一个channel
  8. */
  9. public function __construct()
  10. {
  11. $this->chan = new chan;
  12. }
  13. public function add()
  14. {
  15. $this->count++;
  16. }
  17. public function done()
  18. {
  19. $this->chan->push(true);
  20. }
  21. public function wait()
  22. {
  23. while($this->count--)
  24. {
  25. $this->chan->pop();
  26. }
  27. }
  28. }
  • add方法增加计数
  • done表示任务已完成
  • wait等待所有任务完成恢复当前协程的执行
  • WaitGroup对象可以复用,adddonewait之后可以再次使用

使用实例

  1. go(function () {
  2. $wg = new waitgroup();
  3. $result = [];
  4. $wg->add();
  5. //启动第一个协程
  6. go(function () use ($wg, &$result) {
  7. //启动一个协程客户端client,请求淘宝首页
  8. $cli = new Client('www.taobao.com', 443, true);
  9. $cli->setHeaders([
  10. 'Host' => "www.taobao.com",
  11. "User-Agent" => 'Chrome/49.0.2587.3',
  12. 'Accept' => 'text/html,application/xhtml+xml,application/xml',
  13. 'Accept-Encoding' => 'gzip',
  14. ]);
  15. $cli->set(['timeout' => 1]);
  16. $cli->get('/index.php');
  17. $result['taobao'] = $cli->body;
  18. $cli->close();
  19. $wg->done();
  20. });
  21. $wg->add();
  22. //启动第二个协程
  23. go(function () use ($wg, &$result) {
  24. //启动一个协程客户端client,请求百度首页
  25. $cli = new Client('www.baidu.com', 443, true);
  26. $cli->setHeaders([
  27. 'Host' => "www.baidu.com",
  28. "User-Agent" => 'Chrome/49.0.2587.3',
  29. 'Accept' => 'text/html,application/xhtml+xml,application/xml',
  30. 'Accept-Encoding' => 'gzip',
  31. ]);
  32. $cli->set(['timeout' => 1]);
  33. $cli->get('/index.php');
  34. $result['baidu'] = $cli->body;
  35. $cli->close();
  36. $wg->done();
  37. });
  38. //挂起当前协程,等待所有任务完成后恢复
  39. $wg->wait();
  40. //这里 $result 包含了 2 个任务执行结果
  41. var_dump($result);
  42. });