前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Janus的线程模型

Janus的线程模型

作者头像
音视频_李超
发布2020-05-26 22:04:30
1.2K0
发布2020-05-26 22:04:30
举报
文章被收录于专栏:音视频直播技术专家

我们要想把一个系统搞清楚,首先要把它的线程模型弄明白。比如它是单线程的还是多线程的?如果它是单线程的,那逻辑就比较简单了,像mediasoup就是单进程多实例的模型;如果是多线程的,那它的线程是如何分配的?每个线程的作用是什么?我们必须把这些都要弄清楚才行,否则我们就无法将这个系统彻底搞明白。

在分析 Janus 的时候,我们也应尊循上面的原则。因此在分析Janus之前,我们先来问几个问题,Janus是多线程的模式吗?如果是多线程模式,那它一共有几个线程呢? 这些线程又分别起什么作用?

如果我们将上面的问题回答好了,我想我们基本上就将Janus的线程模型搞清楚了,搞清了它的线程模型也就撑握了Janus的系统大体脉络。

Janus是多线程模式吗?

其实这个问题非常好回答,通过查看Janus的主文件janus.c我们就能知道答案了。在janus.c中我们可以发现下面的代码:

代码语言:javascript
复制
...
GThread *watchdog = g_thread_try_new("timeout watchdog", &janus_sessions_watchdog, watchdog_loop, &error);
...
GThread *requests_thread = g_thread_try_new("sessions requests", &janus_transport_requests, NULL, &error);
...

Janus是基于Linux 的GLIB库开发出来的,因此所有对系统的调用都是使用的GLIB库的API。而g_thread_try_new函数正中GLIB中用来创建线程的,在g_thread_try_new的底层真正调用的是pthread的相关API。

通这上面的分析,我们可以知道Janus是多线程的模式。

Janus一共有几个线程?

除了我们上面介绍的两个线程外,Janus还使用了线程池的概念。在Janus的初始化阶段就将线程池创建出来了。代码如下:

代码语言:javascript
复制
...
tasks = g_thread_pool_new(janus_transport_task, NULL, -1, FALSE, &error);
...

查看g_thread_pool_newAPI的帮助文档,其定义如下:

代码语言:javascript
复制
GThreadPool *
g_thread_pool_new (GFunc func,
                   gpointer user_data,
                   gint max_threads,
                   gboolean exclusive,
                   GError **error);

通过这个定义我们可以知道Janus创建的线程池时并没有对线程数进制控制。也就是说它可以开出系统可以支持的最大限度的线程个数。会在高并发时出现性能问题呢?这个还要等我们后面的深入分析才能清楚,目前来说这行代码还是有风险的。

下面我们总结一下,通过对janus.c文件的分析,我们现在可以知道Janus的线程模型是由两个专用线程watchdogrequest和一个通用任务线程池构成的。如下图所示:

Janus线程模型

了解了Janus的线程模型后,下面我们来看一下 Janus 每个线程的作用吧。

每个线程的作用

通过阅读代码,我们可以了解到这几个线程的主要作用是什么,下面我们来一一介绍一下。

首先是主线程,这个线程的主要作用就是初始化的工作。主要包括以下几方面的工作:

  • 从配置文件中读配置信息,然后根据配置信息进行初始化工作
  • 启动其它线程
  • 动态加载plugin

WatchDog 线程,通过名子我们基本上就可以清楚它的作用了。它是监控线程,它每隔2秒做一次扫描,查看transport的session是否过期了。如果过期了,则给对应的transport发通知让transport结束处理。需要注意的是,这里的 trasnport代表的是不同协议的接入口,如RabbitMQ、MQTT、HTTP等。

Request线程,用于处理接口请求。一般将接口请求分为两大类,文本类请求和命令类请求。如果是文本类请求的,则会启动新线程(从线程池中获取)进行处理;如果是命令的类的,则可以直接处理。当然对于命令类型的Request可能处理上会比较复杂,有可能会分成多个阶段处理,而在每个不同的阶段又会生成新的Request。

最后一个就是线程池了,线程池的作用上面我已经介绍了,就是在处理Request时会从线程池中分配线程,然后执行Request任务,任务完成后再回收到线程池里。

小结

通过上面的描述我们可以看到Janus的线程模型并不复杂,它启动了两个专门的线程,一个用于处理transport的session是否过期;另一个用于处理Request请求,当收到Request请求后,它又会把请求交给新的线程做延时处理。

以上我们就将 Janus 的线程模型分析完了,读到这里我相信你已经对Janus的线程模型有了一个大体的了解了。当然你仍然会很许多疑惑,这只能对照着Janus的代码分析才能让你体会的更深刻!

谢谢!

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Janus是多线程模式吗?
  • Janus一共有几个线程?
  • 每个线程的作用
  • 小结
  • 参考
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档