SRS的启动过程main—SRS源码分析

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

阅读开源项目的代码,有一些技巧与经验分享给大家。

1,首先不要从头文件一个一个看,想一下子把所有变量的含义都搞明白。我以前也用这个方式,后来发现效率太低。变量的含义跟作用应该是要从代码逻辑里面一点点调试来想出来的。基本上,一些比较复杂的变量,你很难从头文件的注释就能立马看懂它的含义。

2,直接找到 main 入口函数,然后直接往下读。用到哪个变量 函数,你再具体去看特定的变量跟函数。用到再看是提高学习效率的方法之一

但是大项目,肯定是有很多逻辑分支的,所以你需要控制好主线,先把项目的架构,模块整理出来,然后逐个击破。切记不要这里看一点,那里看一点,不要被 一些不重要的 if 条件分支转移注意力。

3,一定要用调试器来看代码,哪怕你是在看操作系统的代码,也一定要边调试边看代码。因为只有在调试器下,代码才是活的。如果想了解如何调试操作系统的代码,可以加入张银奎老师的读者群。


SRS 服务器的入口函数是 srs_main_server.cpp 的 main 函数,他的整个启动流程如下:

1-1

下面简单介绍一下重点函数

1,srs_global_initialize()

srs_global_initialize() 里面就是对很多全局变量进行初始化,例如 日志模块(_srs_log),配置文件模块(_srs_config),混合服务模块(_srs_hybrid),熔断模块(_srs_circuit_breaker) 等等。

2,SrsThreadPool::setup_thread_locals()

setup_thread_locals() 里面就是简单地调一下 srs_st_init(),但是也并不简单。由于 SRS 对 StateThreads 协程库进行了多线程改造,所以以前那些 全局变量 都变成了 线程本地变量。

所以,在每次创建线程的时候,都需要调 srs_st_init() 对协程库里面线程本地变量进行初始化。

3,设置协程上下文ID
_srs_context->set_id(_srs_context->generate_id())

这里是设置始祖协程的上下文ID。推荐阅读《SRS的协程ID-SrsContextId


前面的逻辑可以说是一些杂活,真正的重点是 run_directly_or_daemon(),这个函数顾名思义就是直接启动 SRS 或者以守护进程启动 SRS。

run_directly_or_daemon() 内部会创建一个新的线程来运行 run_hybrid_server() 函数,这是一个混合服务,RTMP,SRT,WebRTC 等服务都在 hybird_server 里面。

1-2

关于线程池 ThreadPool 的设计,请阅读《SRS的线程池介绍SrsThreadPool

关于 run_hybrid_server() 的内部实现,请阅读《SRS的混合服务SrsHybridServer


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

results matching ""

    No results matching ""