SRS的协程ID-SrsContextId—SRS源码分析

作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音

SRS 给每个协程都赋予了一个 ID(SrsContextId),由于 SRS 每处理一个 RTMP 客户端连接,都使用一个协程,所以这个 ID 也可以理解为 连接ID,连接ID 就是 SrsRtmpConn 的 ID,这样可以追踪到具体是哪个客户端出现的问题。

协程ID在两个地方都有存储的。

  1. SrsFastCoroutine 类的 cid_ 字段。
  2. 协程的 private data 里面,通过 st_thread_setspecific2() 设置的,请阅读《st_thread_setspecific协程私有数据

但是生成这个协程ID的逻辑是比较绕的,一共有 3 处地方会去设置 协程 ID,如下:

1,SrsFastCoroutine 的构造函数

SrsFastCoroutine 的构造函数可以接收协程 ID,不过有时候传进来的 ID 是空的。所以并没有设置成功,例如 SrsFastTimer 协程。

1-0

1-1

没有成功设置 协程 ID 会怎样呢?会在 SrsFastCoroutine::cycle() 里面再设置一下,现在就来到了第二处设置 协程 ID 的地方。


2,SrsFastCoroutine::cycle()

SrsFastCoroutine::cycle() 里会检测一下 协程ID,如果没设置会再设置一下,如下:

1-3

疑问:上面他为什么要判断一下 _srs_context 是否有值,应该肯定是有值的啊?

这里我有必要介绍一下 _srs_context 这个变量,他是一个全局变量来的。_srs_context 变量的类型虽然是 ISrsContext,但是他的实际却是 SrsThreadContext,如下:

ISrsContext* _srs_context = NULL;
_srs_context = new SrsThreadContext();

SrsThreadContext 类有 3 个方法,如下:

  1. generate_id(),生成一个协程ID 返回。
  2. get_id(),获取当前协程的ID,如果还没有当前协程,会先用 _srs_context_default 来凑数,这个 _srs_context_default 感觉他一直是一个空的东西,没有被赋值。可能 default(默认),默认的协程ID 就是空吧。
  3. set_id(),把协程ID 设置进当前 协程的 private data 里面的。

不要被 _srs_context 这个变量名误导,以为他是某个协程的上下文,他不是,他只是一个管理器。负责生成或者获取协程的ID。


第三处设置协程 ID 的地方就是 SrsFastCoroutine::set_cid() 函数

3,SrsFastCoroutine::set_cid()

SrsFastCoroutine::set_cid() 函数直接就是两个地方的 协程ID 都一下子就设置了,如下:

void SrsFastCoroutine::set_cid(const SrsContextId& cid)
{
    cid_ = cid;
    srs_context_set_cid_of(trd, cid);
}

我觉得前面两处设置 协程 ID 的地方是最重要的,先来讲一下什么场景下传递给 SrsFastCoroutine 构造函数的 协程ID 是空呢?

1-4

SrsThreadPool::setup_thread_locals() 之前创建的协程,他们的 协程ID 都是空。 setup_thread_locals() 里面会调 srs_st_init() 进行初始化协程库。

在此之前,始祖协程都没初始化出来的,所以 srs_thread_self() 获取不到当前协程,就会返回 _srs_context_default,而 _srs_context_default 也没赋值,也是一个空的东西。流程如下:

1-5

他这个逻辑我觉得是有点绕的,反正就是这么一回事。有补救策略,如果在构造函数没成功设置 协程ID,就会在 SrsFastCoroutine::cycle() 里面再设置一下。

不过说实话,我也不太理解 _srs_context_default 这个东西是干什么用的,好像都没对它进行赋值,一直是空。


版权所属 xianwanzhiyin.net 罗上文 2023 all right reserved,powered by Gitbook该文件修订时间: 2024-01-08 01:12:46

results matching ""

    No results matching ""