// #[GetMapping(path: "test")]
function test(){
//使用 create 创建协程
echo '当前协程 ' . Coroutine::id() . PHP_EOL;
Coroutine::create(function () {
echo '使用 create 方法创建协程,协程 ID ' . Coroutine::id() . PHP_EOL;
});
//判断当前环境是否处于协程环境内
var_dump(Coroutine::inCoroutine());
//当前协程id
echo Coroutine::id();
//channel通道
co(function () {//创建协程
//使用通道
$channel = new \Swoole\Coroutine\Channel();
co(function () use ($channel) {
$message = Coroutine::id() . ' ,来自 parent 的数据';
$channel->push($message);
});
$data = $channel->pop();
echo Coroutine::id() . ', 收到 parent 的数据:' . $data . PHP_EOL;
});
//Defer 特性 协程结束时运行一些代码
echo 'start' . PHP_EOL;
go(function () {
echo 'init' . PHP_EOL;
Coroutine::defer(function () {
echo "第一个defer".PHP_EOL;
});
Coroutine::defer(function(){
echo "第二个defer".PHP_EOL;
});
Coroutine::defer(function(){
echo "第三个defer".PHP_EOL;
});
echo 'defer end'.PHP_EOL;
});
echo 'end' . PHP_EOL;
/**
* WaitGroup 特性
* 这段代码创建了一个 WaitGroup 对象 $wg,并通过调用 add 方法将计数器增加了2。
WaitGroup 是 Hyperf 框架提供的一个同步原语,用于协调多个协程的执行。它主要用于等待一组协程执行完成后再继续执行后续逻辑。
在上述代码中,add 方法用于增加计数器的值。通过传入一个正整数作为参数,可以将计数器的值增加相应的次数。在这里,计数器增加了2次,表示有两个协程需要等待。
通常,在创建协程时,我们会使用 go 函数来执行协程任务,并在协程任务执行完成后调用 done 方法来减少计数器的值。当计数器的值减少到0时,表示所有协程任务都已完成,主线程可以继续执行后续逻辑。
*/
$wg = new \Hyperf\Utils\WaitGroup();
// 计数器加二
$wg->add(2);//表示有两个协程需要等待
// 创建协程 A
go(function () use ($wg) {
mt_srand();
$time = mt_rand(1, 3);
sleep($time);
echo "协程 A 执行完成" . PHP_EOL;
// 计数器减一
$wg->done();
});
// 创建协程 B
go(function () use ($wg) {
mt_srand();
$time = mt_rand(1, 3);
sleep($time);
echo "协程 B 执行完成" . PHP_EOL;
// 计数器减一
$wg->done();
});
$wg->wait();
echo "全部程序执行完成" . PHP_EOL;
/**
* 这个应该是最重要的了
* Paraller 特性
* Parallel 特性是 Hyperf 基于 WaitGroup 特性抽象出来的一个更便捷的使用方法。
* use Hyperf\Utils\Exception\ParallelExecutionException;
use Hyperf\Utils\Parallel;
* 这段代码使用了 Parallel 类来并行执行多个协程任务,并获取它们的返回值。
在代码中,首先创建了一个 Parallel 对象,指定并行执行的数量为 10。然后使用 add 方法向 Parallel 对象中添加了 20 个协程任务。每个协程任务都会获取当前的毫秒级时间戳,并将其追加到 a.log 文件中。最后使用 wait 方法等待所有协程任务执行完毕,并获取它们的返回值。
在 try 块中,如果协程任务中出现了异常,可以通过 ParallelExecutionException 异常捕获并处理。可以使用 getResults 方法获取协程任务的返回值,使用 getThrowables 方法获取协程任务中出现的异常。
*/
//同时运行的最大协程数量是 10
//创建了20个协程
//所以分两批执行的 中间间隔5秒
$parallel = new Parallel(10);
for ($i = 0; $i < 20; $i++) {
$parallel->add(function () {
sleep(5);
file_put_contents('./a.log',date('H:i:s'.time()).PHP_EOL,FILE_APPEND);
return Coroutine::id();
});
}
try{
$results = $parallel->wait();
print_r($results);
} catch(ParallelExecutionException $e){
echo $e->getResults();// 获取协程中的返回值。
echo $e->getThrowables();// 获取协程中出现的异常。
}
/**
* Concurrent
* 控制一个代码块内同时运行的最大协程数量
*/
$concurrent = new Coroutine\Concurrent(10);
for ($i = 0; $i < 15; ++$i) {
$concurrent->create(function () {
sleep(1);
echo Coroutine::id() . '==' . mt_rand() . PHP_EOL;
});
}
//协程上下文
go(function () {//创建一个协程 比如id是2
Context::set('name', '王美丽');
go(function () {//创建一个协程 按顺序增加的 id=3
// 不会输出 name 的值
echo Context::get('name');
echo Coroutine::id() . PHP_EOL;
});
// 输出当前协程中 name 的值
Context::override('name');
echo Coroutine::id() . ' ' . Context::get('name');
});
}
协程的使用
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
相关阅读更多精彩内容
- 1. 引言 其实,在每次启动协程都需要一个协程作用域对象,在此处之前的实践代码,用的都是GlobalScope这个...
- 目前找到三种方式 切换到单线程获取单例 使用Coroutine提供的Mutex获取单例 使用CAS(AtomicR...
- 1. 引言 如果学习使用了协程的取消和结构化并发部分的内容,那么协程的异常将是不得不说的内容。 2. 协程的取消异...
- 1. 启动一个协程 来,来启动第一个协程吧: 就这么简单,就可以在任意一个地方启动一个协程,而且这个协程必然会执行...