$count=0;
go(function() use($count){
for($i=1;$i<=3;$i++){
$count=$count+$i;
}
});
echo $count.PHP_EOL;
我们怎么在外部 输出$count值(思考下看视频解释);
认识管道:
<?php
use Swoole\Coroutine as co;
$chan=new co\Channel(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 Swoole\Coroutine 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 Swoole\Coroutine as co;
function query(array $sqls){
$mysql=new co\MySQL();
$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 co\Channel(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
<?php
require_once "vendor/autoload.php";
use App\sync\WaitGroup;
use Swoole\Coroutine as co;
function query(array $sqls){
$mysql=new co\MySQL();
$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;
});
View Code
<?php
namespace App\sync;
use Swoole\Coroutine\Channel;
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();
}
}
}
View Code
defer的使用
练习题1:
<?php
use Swoole\Coroutine as co;
$ques=[
'PHP是不是最好的语言'=>1,
"996恶心吗?"=>1,
"加班是一种福气吗?"=>0
];
$chan=new co\Channel();
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;
}
});
View Code
[root@bogon swoole]# php7 ./class2.php
PHP是不是最好的语言
1
正确
996恶心吗?
1
正确
加班是一种福气吗?
0
正确
View Code
练习题2:
<?php
require __DIR__."/vendor/autoload.php";
use Swoole\Coroutine as co;
go(function(){
$ques=[
'PHP是不是最好的语言'=>1,
"996恶心吗?"=>1,
"加班是一种福气吗?"=>0
];
$wg=new \App\sync\WaitGroup();
$chan=new co\Channel();
$result=new co\Channel(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;
});
View Code
练习题3:统计用户积分
<?php
require_once "vendor/autoload.php";
function grantScore(int $user_id){ //统计积分
(new \App\util\dbutil())->query("select sleep(2) ");//假设这是一个很耗时的 统计用户积分的 过程
return rand(1,10);
}
go(function(){
$users= (new \App\util\dbutil())->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;
}
});
}
});
View Code
更多参考文献 https://github.com/sunlongv520/swoole-co