hyperf协程的理解

发布时间:2021-12-30 11:49:10 阅读:1347次
协程是一种轻量级的线程,由用户代码来调度和管理,而不是由操作系统内核来进行调度,也就是在用户态进行

创建协程方法

<?php

declare(strict_types=1);
namespace AppController;

use HyperfHttpServerContractRequestInterface;
use HyperfUtilsCoroutine;
class CoroutineController extends AbstractController{

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 HyperfUtilsCoroutine;

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方法产生的协程
协程相关方法
判断当前是否处于协程环境(HyperfUtilsCoroutine::inCoroutine(): bool)

HyperfUtilsCoroutine::inCoroutine(): bool
获取当前协程id

HyperfUtilsCoroutine::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 HyperfUtilsExceptionParallelExecutionException;
use HyperfUtilsCoroutine;
use HyperfUtilsParallel;

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

如有问题,可以QQ搜索群1028468525加入群聊,欢迎一起研究技术

支付宝 微信

有疑问联系站长,请联系QQ:QQ咨询

转载请注明:hyperf协程的理解 出自老鄢博客 | 欢迎分享