• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
swoole协程
swoole协程
$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

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/11439413.html

posted on 2019-08-31 16:07  孙龙-程序员  阅读(325)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3