协程是一种轻量级的线程,由用户代码来调度和管理,而不是由操作系统内核来进行调度,也就是在用户态进行
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方法产生的协程
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方法产生的协程
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 主要用于协程间通讯
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
获取子协程数据: 子协程的数据
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
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执行完成 全部程序执行完成
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