当前位置: 首页 > article >正文

SRS代码目录

代码目录:

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(); // 获取当前线程的tid
    entry->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 server
    SrsFastTimer* 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创建SrsServer
    virtual ~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中包含一个HttpServer
	SrsTcpListener* 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.kler.cn/a/530896.html

相关文章:

  • Pandoc, Zotero, JabRef 管理论文引用,生成参考文献 | 撰写论文 paper
  • deep generative model stanford lecture note3 --- latent variable
  • 揭秘算法 课程导读
  • unity学习23:场景scene相关,场景信息,场景跳转
  • 无人机集群新年祝福表演技术原理详解
  • 在Arm芯片苹果Mac系统上通过homebrew安装多版本mysql并解决各种报错,感谢deepseek帮助解决部分问题
  • 中间件的概念及基本使用
  • 基于springboot+vue的航空散货调度系统
  • 五、定时器实现呼吸灯
  • 51单片机 05 矩阵键盘
  • 阿里云盘PC端打不开解决办法
  • [paddle] 矩阵相关的指标
  • Day 27 卡玛笔记
  • 如何在Arduino上使用NodeMCU
  • 基于Kamailio的VoIP管理系统方案(技术栈:MySQL + Redis + Gin + Vue.js
  • 计算机网络网络层进阶:NAT、ARP 与 IP 系列技术全析!!!
  • 业务系统文件上传和互传如何做到高效又安全?
  • 【蓝桥杯】43698.最大比例
  • PageForge v2025.1.2 正式发布:打造现代化的静态站点生成工具
  • HENU~国商计科概率论复习
  • 在Linux环境下修改Anaconda的默认虚拟环境安装位置
  • Deepseek:网页版OR本地部署版本?
  • 【Linux】进程间通信(管道:匿名管道、命名管道、实战练习)
  • IDA Pro的基础指南
  • MiniQMT与xtquant:量化交易的利器
  • Leetcode—81. 搜索旋转排序数组 II【中等】