ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

hyperf 协程理解和使用

2021-09-07 01:02:49  阅读:450  来源: 互联网

标签:function 协程 echo hyperf 理解 test EOL id


协程是一种轻量级的线程,由用户代码来调度和管理,而不是由操作系统内核来进行调度,也就是在用户态进行

创建协程方法

co函数
public function test(){
    echo "first id: ". Coroutine::id().PHP_EOL;
    co(function () {
        echo "second id: ". Coroutine::id().PHP_EOL;
        echo "这是co方法产生的协程".PHP_EOL;
    });
}

访问/index/test

http://ip:9501/index/test

终端显示结果

first id: 2
second id: 3
这是co方法产生的协程
go函数
public function test(){
    echo "first id: ". Coroutine::id().PHP_EOL;
    go(function () {
        echo "second id: ". Coroutine::id().PHP_EOL;
        echo "这是go方法产生的协程".PHP_EOL;
    });
}

访问/index/test

http://ip:9501/index/test

终端显示结果

first id: 2
second id: 3
这是go方法产生的协程

Coroutine::create方法

use Hyperf\Utils\Coroutine;

public function test(){
    echo "first id: ". Coroutine::id().PHP_EOL;
    Coroutine::create(function(){
        echo "second id: ". Coroutine::id().PHP_EOL;
        echo "这是coroutine::create方法产生的协程".PHP_EOL;
    });
}

访问/index/test

http://ip:9501/index/test

终端显示结果

first id: 2
second id: 3
这是coroutine::create方法产生的协程

协程相关方法

判断当前是否处于协程环境(Hyperf\Utils\Coroutine::inCoroutine(): bool)

Hyperf\Utils\Coroutine::inCoroutine(): bool

获取当前协程id

Hyperf\Utils\Coroutine::id()

channel通道

Channel 主要用于协程间通讯

public function test(){
    co(function () {
        $channel = new \Swoole\Coroutine\Channel();
        co(function () use ($channel) {
            $channel->push('子协程的数据');
        });
        $data = $channel->pop();
        echo "获取子协程数据: ".$data;
    });
}

访问/index/test

http://ip:9501/index/test
获取子协程数据: 子协程的数据

defer特性

public function test(){
    Coroutine::defer(function(){
        echo "第一个defer".PHP_EOL;
    });
    Coroutine::defer(function(){
        echo "第二个defer".PHP_EOL;
    });
    Coroutine::defer(function(){
        echo "第三个defer".PHP_EOL;
    });
    echo 'defer test'.PHP_EOL;
}

访问/index/test

http://ip:9501/index/test

终端结果显示

defer test
第三个defer
第二个defer
第一个defer

WaitGroup特性

public function test(){
    $wg = new \Hyperf\Utils\WaitGroup();
    // 计数器加二
    $wg->add(2);
    // 创建协程 A
    co(function () use ($wg) {
           mt_srand();
           $time = mt_rand(1, 5);
           sleep($time);
           // some code
           echo "协程A执行完成".PHP_EOL;
           //计算器减一
           $wg->done();
    });
    // 创建协程 B
    co(function () use ($wg) {
           mt_srand();
           $time = mt_rand(1, 5);
           sleep($time);
           // some code
           echo "协程B执行完成".PHP_EOL;
           // 计数器减一
           $wg->done();
    });
    // 等待协程 A 和协程 B 运行完成
    $wg->wait();
    echo "全部程序执行完成".PHP_EOL;
}

访问/index/test

http://ip:9501/index/test

终端结果显示

协程B执行完成
协程A执行完成
全部程序执行完成

Parallel特性

use Hyperf\Utils\Exception\ParallelExecutionException;
use Hyperf\Utils\Coroutine;
use Hyperf\Utils\Parallel;


public function test(){
    $parallel = new Parallel();
    $parallel->add(function () {
        mt_srand();
        $time = mt_rand(1, 5);
        sleep($time);
        echo "协程A执行完成".PHP_EOL;
        return Coroutine::id();
    });
    $parallel->add(function () {
        mt_srand();
        $time = mt_rand(1, 5);
        sleep($time);
        echo "协程B执行完成".PHP_EOL;
        return Coroutine::id();
    });

    try{
        // $results 结果为 [1, 2]
        $results = $parallel->wait();
        echo "results:".PHP_EOL;
        var_dump($results);
    } catch(ParallelExecutionException $e){
        // $e->getResults() 获取协程中的返回值。
        // $e->getThrowables() 获取协程中出现的异常。
        var_dump($e->getResults());
    }

}

访问/index/test

http://ip:9501/index/test

终端结果显示

协程B执行完成
协程A执行完成
results:
array(2) {
  [1]=>
  int(4)
  [0]=>
  int(3)
}

简写版

$results = parallel([
    function () {
        mt_srand();
        $time = mt_rand(1, 5);
        sleep($time);
        echo "协程A执行完成".PHP_EOL;
        return Coroutine::id();
    },
    function () {
        mt_srand();
        $time = mt_rand(1, 5);
        sleep($time);
        echo "协程B执行完成".PHP_EOL;
        return Coroutine::id();
    }
]);

协程上下文

public function test(){
    co(function(){
        Context::set('name','huyongjian');
        $name = Context::get('name');
        echo $name.PHP_EOL;
    });
}

访问/index/test

http://ip:9501/index/test

终端结果显示

huyongjian

标签:function,协程,echo,hyperf,理解,test,EOL,id
来源: https://www.cnblogs.com/hu308830232/p/15236444.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有