$count=0; go(function() use($count){ for($i=1;$i<=3;$i++){ $count=$count+$i; } }); echo $count.PHP_EOL; 我们怎么在外部 输出$count值(思考下看视频解释);
认识管道:
<?php use SwooleCoroutine as co; $chan=new coChannel(1); go(function() use($chan){ //只负责 计算 cpu $count=0; for($i=1;$i<=3;$i++){ $count=$count+$i; co::sleep(1); } $chan->push($count); }); go(function() use($chan){ //只负责输出 IO echo $chan->pop().PHP_EOL; });
协程的切换、手动挂起协程
<?php use SwooleCoroutine as co; $cid = go(function(){ for($i=1;$i<=10;$i++){ if($i == 6) co::yield(); echo $i.PHP_EOL; co::sleep(0.1); } }); go(function() use ($cid){ for($i=1;$i<=10;$i++){ echo 'a'.$i.PHP_EOL; co::sleep(0.1); } co::resume($cid); });
[root@bogon swoole]# php7 ./class2.php 1 a1 2 a2 3 a3 a4 4 5 a5 a6 a7 a8 a9 a10 6 7 8 9 10
使用多协程按顺序执行
<?php use SwooleCoroutine as co; function query(array $sqls){ $mysql=new coMySQL(); $conn=$mysql->connect(['host' => '127.0.0.1', 'user' => 'root', 'password' => 'root', 'database' => 'test2',]); foreach($sqls as $sql){ $statement=$mysql->prepare($sql); $rows=$statement->execute(); foreach($rows as $row){ foreach($row as $k=>$v){ echo $k."=>".$v.";"; } } } echo PHP_EOL; } go(function(){ $chan=new coChannel(2); go(function() use($chan){ query(["select sleep(2)","select * from users where user_id=1"]); $chan->push(1); }); go(function() use($chan){ query(["select * from users where user_id=2"]); $chan->push(2); }); for($i=0;$i<2;$i++){ $chan->pop(); } echo "done".PHP_EOL; });
模仿golang的WaitGroup
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php require_once "vendor/autoload.php"; use AppsyncWaitGroup; use SwooleCoroutine as co; function query(array $sqls){ $mysql=new coMySQL(); $conn=$mysql->connect(['host' => '192.168.29.1', 'user' => 'shenyi', 'password' => '123123', 'database' => 'test',]); foreach($sqls as $sql){ $statement=$mysql->prepare($sql); $rows=$statement->execute(); foreach($rows as $row){ foreach($row as $k=>$v){ echo $k."=>".$v.";"; } } } echo PHP_EOL; } go(function(){ $wg=new WaitGroup(); $wg->Add(2);//设置协程的数量 go(function() use($wg){ query(["select sleep(2)","select * from users where user_id=1"]); $wg->Done(); }); go(function() use($wg){ query(["select * from users where user_id=2"]); $wg->Done(); }); $wg->Wait(); echo "done".PHP_EOL; });
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php namespace Appsync; use SwooleCoroutineChannel; class WaitGroup{ private $chan; private $count; function __construct() { $this->chan=new Channel(1); $this->count=0; } public function Add(int $c){ $this->count+=$c; } public function Done(){ $this->chan->push(1); } public function Wait(){ for($i=0;$i<$this->count;$i++){ $this->chan->pop(); } } }
defer的使用
练习题1:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php use SwooleCoroutine as co; $ques=[ 'PHP是不是最好的语言'=>1, "996恶心吗?"=>1, "加班是一种福气吗?"=>0 ]; $chan=new coChannel(); go(function() use($ques,$chan){ $ques['end']=-1; foreach($ques as $que=>$ans) { $chan->push($que); } }); go(function() use($ques,$chan){ while (true){ $getQues=$chan->pop(); if($getQues=="end") break; echo $getQues.PHP_EOL; $getAns=fgets(STDIN); if($getAns==$ques[$getQues]){ echo "正确".PHP_EOL; } else echo "错误".PHP_EOL; } });
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@bogon swoole]# php7 ./class2.php PHP是不是最好的语言 1 正确 996恶心吗? 1 正确 加班是一种福气吗? 0 正确
练习题2:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php require __DIR__."/vendor/autoload.php"; use SwooleCoroutine as co; go(function(){ $ques=[ 'PHP是不是最好的语言'=>1, "996恶心吗?"=>1, "加班是一种福气吗?"=>0 ]; $wg=new AppsyncWaitGroup(); $chan=new coChannel(); $result=new coChannel(3); $wg->Add(2); go(function() use($ques,$chan,$wg){ $ques['end']=-1; foreach($ques as $que=>$ans) { $chan->push($que); } $wg->Done(); }); go(function() use($ques,$chan,$result,$wg){ while (true){ $getQues=$chan->pop(); if($getQues=="end") break; echo $getQues.PHP_EOL; $getAns=fgets(STDIN); $result->push($getAns==$ques[$getQues]?1:0); } $wg->Done(); }); $wg->Wait(); echo "开始计算结果".PHP_EOL; $score=0; for($i=0;$i<count($ques);$i++){ $score+=$result->pop(); } echo "您的得分是:$score".PHP_EOL; });
练习题3:统计用户积分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?php require_once "vendor/autoload.php"; function grantScore(int $user_id){ //统计积分 (new Apputildbutil())->query("select sleep(2) ");//假设这是一个很耗时的 统计用户积分的 过程 return rand(1,10); } go(function(){ $users= (new Apputildbutil())->query("select user_id from users");// 取出所有用户 $arrs=array_chunk($users,2); // [[],[],[] ,[]]; foreach ($arrs as $users){ go(function() use($users){ foreach ($users as $user){ $score= grantScore($user["user_id"]); echo "userid=".$user["user_id"]."的积分是:".$score.PHP_EOL; } }); } });
更多参考文献 https://github.com/sunlongv520/swoole-co