Coroutine::getCid

最后更新于:2022-04-02 06:25:47

# Coroutine::getCid [TOC] 获取当前协程的唯一`ID`, 它的别名为`getUid`, 是一个进程内唯一的正整数 ~~~ function \Swoole\Coroutine::getCid() : int ~~~ > 仅在当前进程内唯一 ## 返回值 * 成功时返回当前协程`ID(int)` * 如果当前不在协程环境中,则返回`-1` ~~~ echo Swoole\Coroutine::getCid(); ~~~ ## cid分配机制 在v4.2.9中, cid分配机制从有限的`cidmap+静态表`更改为`unordered_map`, 底层的cid改为long类型, 分配方式为自增, 在PHP中最大值为`PHP_INT_MAX`, 在64位机器上其大小为`9223372036854775807`, 几乎不存在重复的可能性, 可以作为真正的`unique id`而无需考虑cid在进程内的可能重复的问题. ## cid分配机制 (v4.2.8及以下版本) > [相关issue](https://github.com/swoole/swoole-src/issues/1977) > > 如在v4.2.8及以下版本使用cid作为上下文存储主键, 而在协程退出时没有妥善清除上下文, cid的复用(创建超过52万个协程后)可能会导致协程上下文错乱 cid map 使用了 bit map, 它在分配时总是会寻找下一个可用的比特位 我们可以通过以下代码来确认这个事实: ~~~ co::set([ 'max_coroutine' => PHP_INT_MAX, 'log_level' => SWOOLE_LOG_INFO, 'trace_flags' => 0 ]); $map = []; while (true) { if (empty($map)){ $cid = go(function () {co::sleep(5);}); }else{ $cid = go(function () { }); } if (!isset($map[$cid])) { $map[$cid] = $cid; } else { var_dump(end($map)); var_dump($cid); exit; } } ~~~ 它将会打印: ~~~ int(524288) int(2) ~~~ 所以我们有`MAX_CORO_NUM_LIMIT => 0x80000`则在同一时间同一进程的协程数也不能超过`524288` 虽然它的分配数量存在上限, 但这个数值非常大, 一个进程不可能同时存在这么多协程, 除非你有一台超大内存的机器, 但那时候你也不必再担心这个问题
';