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

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 这个东西是干什么用的,好像都没对它进行赋值,一直是空。


本文是《SRS原理》一书中的文章,如需观看更多内容,请购买本书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值