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`
虽然它的分配数量存在上限, 但这个数值非常大, 一个进程不可能同时存在这么多协程, 除非你有一台超大内存的机器, 但那时候你也不必再担心这个问题
';