SRS的信号处理模块SrsSignalManager—SRS源码分析

SrsSignalManager 就是 SRS 的信号处理模块,他的主要逻辑是把 信号事件 转换成 IO 事件,这样就能用协程来处理了。关于 信号 转 IO 可以阅读之前的文章《HTTP服务器server程序信号处理

SrsSignalManager 模块使用的是 SRS 封装 StateThreads 协程之后的 API,也就是《SRS对StateThreads的封装》介绍的方法。

SrsSignalManager 实际上是一个 Handler ,因为它继承的是ISrsCoroutineHandler。SRS 封装后的协程的用法是在构造函数里面把 Handler 注册进去 SrsSTCoroutine 协程,如下:

kotlin 复制代码
class SrsSignalManager : public ISrsCoroutineHandler

然后 SrsSTCoroutine 协程内部会调 _pfn_st_thread_create() 创建一个协程,最终会运行 Handlercycle() 方法,如下:


下面介绍一下 SrsSignalManager 类里面一些重点字段跟方法。

1,int sig_pipe[2]

这是用 pipe() 函数创建的两个文件描述符,关于 pipe 管道的用法,推荐阅读《Unix环境高级编程》。

2,srs_netfd_t signal_read_stfd

signal_read_stfd 是经过 StateThreads 协程库封装之后的 文件描述符,实际上就是对 sig_pipe[0] 的封装,如下:

arduino 复制代码
if ((signal_read_stfd = srs_netfd_open(sig_pipe[0])) == NULL) {
    return srs_error_new(ERROR_SYSTEM_CREATE_PIPE, "open pipe");
}

可能这里读者有点疑惑,前面 sig_pipe[] 数组里面明明有两个文件描述符,为什么只针对 read 描述符 进行 srs_netfd_open() 封装?为什么没有定义一个 signal_write_stfd 变量出来

答:因为这类似于 生产与消费者模式,写的时候直接写就行了,读的时候才需要阻塞事件监控。所以他写是直接往 sig_pipe[1] 里面写数据就行了,不需要用协程库对 write fd 进行监控。


3,SrsServer* server

SrsSignalManager 是绑定在 SrsServer 里面的,他们之间的关系如下:

4,SrsCoroutine* trd

trd 是信号模块对应的 协程实例 ,其他模块也是一样的用法,变量名都叫 trd

5,static SrsSignalManager* instance

注意 instance 是一个 static 静态变量,所以可以直接 SrsSignalManager::instance 调用的,他这样是把自己变成了一个带 命名空间的 全局变量,前缀 SrsSignalManager:: 可以理解为 命名空间的用法。

instance 是在构造函数里面把自己赋值进去的,如下:


SrsSignalManager 类里面的重点的方法如下:

1,virtual srs_error_t initialize()

initialize() 主要是创建 管道描述符。

2,virtual srs_error_t start()

start() 函数主要设置 信号的处理函数,哪些信号 由 哪些函数 来处理。start() 是在 SrsServer::register_signal 里面被调用的,如下:

3,virtual srs_error_t cycle()

cycle() 就是协程里运行的函数,所有模块的协程函数 都是叫 cycle 的。在信号处理模块,cycle() 主要是不断阻塞读取 管道描述符的 数据,当产生信号的时候 管道描述符就会有数据到来,然后 cycle() 进行处理。

那是在哪里往管道描述符写入数据的呢?

答:在 SrsSignalManager::sig_catcher() 里,因为之前在 SrsSignalManager::start() 已经把所有信号的处理函数都设置成了 sig_catcher()

所以当信号产生的时候,代码的执行位置就会跳进去 sig_catcher() 函数,也可以理解为 rip 寄存器跳到 sig_catcher() 了。信号是可以在任何时候产生的,所以任何时候都有机会跳进去 sig_catcher() 函数。

sig_catcher() 就负责往 管道描述符 写入数据,如下:


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

相关推荐
SHERlocked932 天前
摄像头 RTSP 流视频多路实时监控解决方案实践
c++·后端·音视频开发
mortimer16 天前
Python + FFmpeg 视频自动化处理指南:从硬件加速到精确剪辑
python·ffmpeg·音视频开发
否子戈17 天前
做中国人自己的视频编辑UI框架,WebCut正式开源
前端框架·音视频开发·视频编码
音视频牛哥18 天前
从低延迟到高可用:RTMP与 HTTP/HTTPS-FLV在App播放体系中的角色重构
人工智能·音视频·音视频开发·http-flv播放器·https-flv播放器·ws-flv播放器·wss-flv播放器
音视频牛哥23 天前
轻量级RTSP服务的工程化设计与应用:从移动端到边缘设备的实时媒体架构
人工智能·计算机视觉·音视频·音视频开发·rtsp播放器·安卓rtsp服务器·安卓实现ipc功能
快乐10124 天前
Media3 ExoPlayer无法播放不带.m3u8后缀hls媒资
音视频开发
_AaronWong25 天前
基于 Vue 3 的屏幕音频捕获实现:从原理到实践
前端·vue.js·音视频开发
快手技术1 个月前
超越 VTM-RA!快手双向智能视频编码器 BRHVC 亮相 NeurIPS2025
音视频开发
快乐1011 个月前
Media3 ExoPlayer扩展切换声道能力
音视频开发
yangguang1 个月前
音视频开发全景图:播放器是怎样炼成的
音视频开发