× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

Coroutine::getContext

v4.3.0后可用

获取当前协程的上下文对象

function Coroutine::getContext([$cid]) : 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