SRS代码目录

devtools/2025/2/5 3:31:15/

代码目录:

src/目录下核心代码:
在这里插入图片描述

  • core:核心功能模块,包括日志、配置、错误处理等;
  • protocol:实现RTMP、HTTP-FLV、HLS等协议的模块;
  • app:应用层的实现,包括流的发布、播放、转码等功能;
  • kernel:底层实现,包括网络I/O、多线程处理等;
  • main:主层序入口

SRS启动:

main:

// src/main/srs_main_server.cpp
main()
{do_main();
}do_main()
{// 初始化,new创建各种server和实例srs_global_initialize();// 启动线程池?SrsThreadPool::setup_thread_locals();// 加载conf配置_srs_config->parse_options(argc, argv);// 运行主程序run_directly_or_daemon();
}

srs_global_initialize: 初始化各种server

// src/app/srs_app_threads.cpp
srs_global_initialize()
{...// 全局变量 _srs_hybrid:// SrsHybridServer* _srs_hybrid = NULL;_srs_hybrid = new SrsHybridServer();...
}

run_directly_or_daemon: 开始运行

run_directly_or_daemon()
{// 我们没有配置为daemon...int pid = fork();if (pid > 0) {// 父进程直接退出exit(0);}// 继续第二次fork()pid = fork();if (pid > 0) {// 父进程退出exit(0);}// 在子进程中开启执行run_in_thread_pool();
}

run_in_thread_pool

run_in_thread_pool()
{// 初始化线程池_srs_thread_pool->initialize();// 创建run_hybrid_server 工作线程,用于RTMP、RTC server_srs_thread_pool->execute("hybrid", run_hybrid_server, (void*)NULL)// 循环执行线程池中的每个线程:_srs_thread_pool->run();
}

SRS中的线程:

SrsThreadPool 线程池类:

// src/app/srs_app_threads.hpp
class SrsThreadPool {//std::vector<SrsThreadEntry*> threads_;//std::vector<SrsThreadEntry*> hybrids_;
};// 线程池构造函数中,先指定主线程(primordial thread)
// primordial thread并不是调用pthread_create()单独创建的,而是指向了当前调用线程
SrsThreadPool::SrsThreadPool() {entry_ = NULL;lock_ = new SrsThreadMutex();hybrid_ = NULL;// Add primordial thread, current thread itself.SrsThreadEntry* entry = new SrsThreadEntry();threads_.push_back(entry); // 插入到线程池中entry_ = entry;entry->pool = this;entry->label = "primordial";entry->start = NULL;entry->arg = NULL;entry->num = 1;entry->trd = pthread_self(); // 获取当前线程的tidentry->tid = gettid();char buf[256];snprintf(buf, sizeof(buf), "srs-master-%d", entry->num);entry->name = buf;pid_fd = -1;
}

SrsThreadEntry 线程类:

// src/app/srs_app_threads.hpp
class SrsThreadEntry {SrsThreadPool* pool; // 此线程所在的线程池pid_t 		tid;pthread_t 	trd;string		name;srs_error_t (*start)(void* arg); // 线程入口函数void* arg; // 线程入参
};

_srs_thread_pool是一个全局变量,启动时初始化:

SrsThreadPool* _srs_thread_pool = new SrsThreadPool();

SRS中的Server:

hybrid_server:

// 虚基类,为不同的server子类提供接口
// The hyrid server interfaces, we could register many servers.
class ISrsHybridServer {
public:ISrsHybridServer();virtual ~ISrsHybridServer();
public:virtual srs_error_t initialize() = 0;virtual srs_error_t run(SrsWaitGroup* wg) = 0;virtual void stop() = 0;
};// 管理hybrid server的类
// The hybrid server manager.
class SrsHybridServer : public ISrsFastTimer {
private:std::vector<ISrsHybridServer*> servers; // 管理所有hybrid serverSrsFastTimer* timer20ms_;...virtual void register_server(ISrsHybridServer* svr);
};

SRS中hybrid server类型:

// The SRS server adapter, the master server.
class SrsServerAdapter : public ISrsHybridServer;
// The RTC server adapter.
class RtcServerAdapter : public ISrsHybridServer;
// The srt server adapter, the master server.
class SrsSrtServerAdapter : public ISrsHybridServer;

正如其类名中的“Adapter”所示,这些类是适配类,核心类型是其中真正的server,如SrsServerAdapter中的SrsServer成员、RtcServerAdapter中的SrsRtcServer成员。

SrsServer:

class SrsServerAdapter : public ISrsHybridServer {
private:SrsServer* srs;
public:SrsServerAdapter();	// new创建SrsServervirtual ~SrsServerAdapter();
public:virtual srs_error_t initialize();// 调用SrsServer中的initialize等函数完成初始化,并调用SrsServer->start()virtual srs_error_t run(SrsWaitGroup* wg); virtual void stop();
public:virtual SrsServer* instance();
}; SrsServerAdapter::SrsServerAdapter()
{srs = new SrsServer();
}

SrsServer:

class SrsServer : public ISrsReloadHandler, public ISrsLiveSourceHandler, public ISrsTcpHandler, public ISrsResourceManager, public ISrsCoroutineHandler, public ISrsHourGlass
{
private:SrsHttpServer* http_server; // SrsServer中包含一个HttpServerSrsTcpListener* api_listener_;SrsTcpListener* http_listener_;SrsTcpListener* webrtc_listener_;...
};

SrsRtcServer:

class RtcServerAdapter : public ISrsHybridServer {
private:SrsRtcServer* rtc;
};

gdb:

使用 GDB 调试程序并传递命令行参数:

gdb --args ./objs/srs -c conf/srs.conf

禁用 LeakSanitizer(设置环境变量):

export LSAN_OPTIONS=detect_leaks=0

gdb与fork:

当程序中调用for()创建子进程时,gdb默认只会继续调试父进程,而会“分离”或忽略子进程。
这是因为gdb通常只调试一个进程。
如果需要控制gdb调试指定父进程或子进程,需要通过特定的调试设置来改变这一行为:

(gdb) set follow-fork-mode child  # 调试子进程
(gdb) set follow-fork-mode parent  # 调试父进程

查看当前follow-fork-mode的值:

(gdb) show follow-fork-mode

常用gdb命令:

c:continue,跳到下一个断点
n:next,调到下一个函数(不进入函数内部)
s:step,进入函数内部
finish:完成函数

r:从头开始

info threads: 查看当前有多少个线程
info inferiors: 查看当前有多少个进程


http://www.ppmy.cn/devtools/156160.html

相关文章

普罗米修斯监控服务搭建位置全解析:权衡与抉择

在数字化时代&#xff0c;监控系统对于企业的稳定运营和业务发展至关重要。普罗米修斯作为一款备受青睐的开源监控和告警工具&#xff0c;其搭建位置的决策绝非小事&#xff0c;它紧密关联着监控系统的性能、可靠性与安全性&#xff0c;如同为整座大厦奠定基石。接下来&#xf…

npm 和 pip 安装中常见问题总结

安装路径的疑惑&#xff1a;NPM 和 PIP 的安装机制 NPM 安装路径规则&#xff1a; 依赖安装在项目目录下&#xff1a; 当你运行 npm install --save-dev jest&#xff0c;它会在当前目录&#xff08;例如 F:\&#xff09;下创建一个 node_modules 文件夹&#xff0c;把 jest 安…

MySQL为什么默认引擎是InnoDB ?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL为什么默认引擎是InnoDB &#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL为什么默认引擎是InnoDB &#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 默认引擎是 InnoDB&#xff0c;主要…

第五章:元婴-React用户功能实战

文章目录 登录页面布局JWT 令牌鉴权用户功能实现用户查询页面用户更改状态用户添加页面用户添加页面表单构建用户编辑页面用户编辑表单页面登录页面布局 import React, { useEffect, useState } from react import { Button, Form, Input, message } from antd import style fr…

第三周 树

猫猫和企鹅 分数 10 全屏浏览 切换布局 作者 姜明欣 单位 河北大学 王国里有 nn 个居住区&#xff0c;它们之间有 n−1 条道路相连&#xff0c;并且保证从每个居住区出发都可以到达任何一个居住区&#xff0c;并且每条道路的长度都为 1。 除 1号居住区外&#xff0c;每个居…

DeepSeek-R1 论文. Reinforcement Learning 通过强化学习激励大型语言模型的推理能力

论文链接&#xff1a; [2501.12948] DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning 实在太长&#xff0c;自行扔到 Model 里&#xff0c;去翻译去提问吧。 工作原理&#xff1a; 主要技术&#xff0c;就是训练出一些专有用途小模型&…

记忆化搜索和动态规划 --最长回文子串为例

记忆化搜索 记忆化搜索是一种优化递归算法的方法&#xff0c;通过将已经计算过的子问题的结果存储起来&#xff08;通常使用哈希表或数组&#xff09;&#xff0c;避免重复计算相同的子问题。 本质上是通过缓存中间结果来减少计算的重复性。 动态规划 动态规划是通过将问题分…

[STM32 标准库]定时器输出PWM配置流程 PWM模式解析

前言&#xff1a; 本文内容基本来自江协&#xff0c;整理起来方便日后开发使用。MCU&#xff1a;STM32F103C8T6。 一、配置流程 1、开启GPIO&#xff0c;TIM的时钟 /*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟RCC_APB2PeriphClockC…