Coroutine::getContext
最后更新于:2022-04-02 06:25:52
# Coroutine::getContext
[TOC]
> v4.3.0后可用
获取当前协程的上下文对象
~~~
function Coroutine::getContext() : Coroutine\Context
~~~
接受一个可选参数cid, 默认返回当前协程的上下文对象
## 代码
~~~
function func(callable $fn, ...$args)
{
go(function () use ($fn, $args) {
$fn(...$args);
echo 'Coroutine#' . Co::getCid() . ' exit' . PHP_EOL;
});
}
/**
* Compatibility for lower version
* @param object|Resource $object
* @return int
*/
function php_object_id($object)
{
static $id = 0;
static $map = [];
$hash = spl_object_hash($object);
return $map[$hash] ?? ($map[$hash] = ++$id);
}
class Resource
{
public function __construct()
{
echo __CLASS__ . '#' . php_object_id((object)$this) . ' constructed' . PHP_EOL;
}
public function __destruct()
{
echo __CLASS__ . '#' . php_object_id((object)$this) . ' destructed' . PHP_EOL;
}
}
$context = new Co\Context();
assert($context instanceof ArrayObject);
assert(Co::getContext() === null);
func(function () {
$context = Co::getContext();
assert($context instanceof Co\Context);
$context['resource1'] = new Resource;
$context->resource2 = new Resource;
func(function () {
Co::getContext()['resource3'] = new Resource;
Co::yield();
Co::getContext()['resource3']->resource4 = new Resource;
Co::getContext()->resource5 = new Resource;
});
});
Co::resume(2);
~~~
## 输出
~~~
Resource#1 constructed
Resource#2 constructed
Resource#3 constructed
Coroutine#1 exit
Resource#2 destructed
Resource#1 destructed
Resource#4 constructed
Resource#5 constructed
Coroutine#2 exit
Resource#5 destructed
Resource#3 destructed
Resource#4 destructed
~~~
## 作用
* 协程退出后上下文自动清理 (如无其它协程或全局变量引用)
* 无defer注册和调用的开销 (无需注册清理方法, 无需调用函数清理)
* 无PHP数组实现的上下文的哈希计算开销 (在协程数量巨大时有一定好处)
* `Co\Context`使用ArrayObject, 满足各种存储需求 (既是对象, 也可以以数组方式操作)
## 实现
https://github.com/swoole/swoole-src/pull/2399
';