ZLMediaKit中的线程

news2024/12/23 7:14:05

EventLoop的线程模型

服务器通用的IO模型event-loop + 非阻塞IO。线程模型可以是单线程,可以是多线程。对于已经普及了的多核环境,通常都是采用多线程。

通常一个线程中有一个EventLoop,比如accept是一个专门线程,accept后的fd分到不同线程中,一个fd只会在一个EventLoop中处理。那么也可以说是一个EventLoop就代表了一个线程。在ZLMediaKit中线程就是这种抽象。

EventLoop的基本实现就是IO多路复用(select,epoll等)+消息队列,它不止可以用于处理IO。也可以当作消息队列或定时器使用。

这种方式非常适用于对线程职责的划分,将特定的业务通过消息队列分到固定的线程。在webrtc中,rtc::thread也是种实现。它同时作为网络线程,信令线程,工作线程使用。其中工作线程并没有IO功能。 详细见webrtc中的rtc::thread

ZLMediaKit中的EventLoop

线程

EventLoop在众多的开源网络库都有实现。ZLMediaKit的实现非常适合用于多线程模型。

企业微信截图_17014217474387.png

以上为其类图,EventPoller就是EventLoop,为一个事件循环。它继承自TaskExecutor,代表了一个线程。

其中的方法asyncsync分别代表着向线程投递异步任务同步任务(在TaskExecutorInterface中定义)。它还包括了计算CPU负载的功能(在ThreadLoadCounter中定义)。

所以EventPoller是一个功能相当完备的线程:

  • 有事件循环
  • 可以向其投递任务。
  • 可以计算CPU负载,结合线程池一起使用,选取负载低的线程。

线程池

企业微信截图_1701421705841.png

以上为ZLMediaKit中线程池类图,通过EventPollerPoollgetPollergetFirstPoller方法来取一个线程(EventPoller)。getPoller优先取一个CPU负载小的线程。

使用

产生一个线程

在ZLMediaKit中通过EventPollerPool来获取一个EventPoller,如下代码:

EventPollerPool::setPoolSize(thread_num);
auto poller = EventPollerPool::Instance().getPoller();

EventPollerPool::setPoolSize(thread_num)设置线程数,当产生线程池对象EventPollerPool时,线程都已创建并绑定到了核上,通过getPoller()方法获取一个CPU负责最小的线程。上面的poller对象就代表了一个线程。

向线程投递一个任务

通过async,比如如下代码:

poller->async([invoker,contentOut](){
                HttpSession::KeyValue headerOut;
                //你可以自定义header,如果跟默认header重名,则会覆盖之
                //默认header有:Server,Connection,Date,Content-Type,Content-Length
                //请勿覆盖Connection、Content-Length键
                //键名覆盖时不区分大小写
                headerOut["TestHeader"] = "HeaderValue";
                invoker(200,headerOut,contentOut);
            });

通过doDelayTask向线程投递定时任务,如下代码:

poller->doDelayTask((uint64_t) (second * 1000), [cb, second]() {
        try {
            if (cb()) {
                //重复的任务
                return (uint64_t) (1000 * second);
            }
            //该任务不再重复
            return (uint64_t) 0;
        } catch (std::exception &ex) {
            ErrorL << "Exception occurred when do timer task: " << ex.what();
            return (uint64_t) (1000 * second);
        }
    });

瑕疵

  • EventPoller的构造函数都被设置为了私有,只能通过EventPollerPool::Instance().getPoller()获取,这有些不方便。在一些场景,程序会被划分成了固定的线程,而不需要使用线程池。
  • 如果能提供将当前线程保证成EventPoller线程的功能就更好了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1309019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

I.MX RT1170双核学习(2):双核相互激活和启动流程

RT1170这个芯片带有双核&#xff1a;Cortex-M7和Corterx-M4&#xff0c;两个核都可以独立地运行&#xff0c;当然双核也可以同时运行。在上一篇文章中&#xff0c;介绍了一下在RT1170中消息模块MU的使用&#xff1a;双核通信之MU消息单元详解&#xff0c;因为这是双核之间用来通…

基于Dockerfile创建LNMP

实验组件 172.111.0.10&#xff1a;nginx docker-nginx 172.111.0.20&#xff1a;mysql docker-mysql 172.111.0.30&#xff1a;php docker-php 实验步骤 1.建立nginx-lnmp镜像及容器 cd /opt mkdir nginx cd nginx/ --上传nginx-1.22.0.tar.gz和wordpress-6.4.2-zh_C…

JOSEF 约瑟 时间继电器 DHC6A AC/DC100-240V 面板安装

特点 DIN&#xff08;4848mm&#xff09;标准面板尺寸 9 种工作模式可任意设定&#xff0c;简化外围线路,增强可靠性 带背光源 LCD 显示&#xff0c;在阳光或黑夜都能清晰显示 键保护可按要求锁定相关的按键,保护部分或全部的设定数据不受更 改&#xff0c;有效的防止误操…

02-详解请求路由的实现和常见的断言工厂

请求路由 路由转发 第一步: 新建一个SpringBoot工程如gateway模块, 引入网关依赖和nacos服务发现依赖 <!--网关依赖--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId&…

【免费神器】一键转换PDF文件,轻松解决你的烦恼!

你是否曾经因为PDF文件的格式问题而感到困扰&#xff1f;是否曾经因为无法快速转换PDF文件而感到烦恼&#xff1f; 现在&#xff0c;这些问题都可以迎刃而解了&#xff01;下面这个在线PDF转换网站&#xff0c;就是你的解决方案。 目前5M以下文件免费转换&#xff0c;赶紧来看…

Python-自制简易音乐播放器

文章目录 前言一、代码二、代码实现1.库2.做ui窗口3爬虫 前言 原理简单&#xff1a;通过外链和歌曲Id拼接成下载链接来下载歌曲。 一、代码 做了个ui输入歌单链接&#xff1a; 注意这里歌单的url格式固定: https://music.163.com/playlist?id歌单id import sys from PyQt5.…

JavaWeb笔记之MySQL数据库

#Author 流云 #Version 1.0 一、引言 1.1 现有的数据存储方式有哪些&#xff1f; Java程序存储数据&#xff08;变量、对象、数组、集合&#xff09;&#xff0c;数据保存在内存中&#xff0c;属于瞬时状态存储。 文件&#xff08;File&#xff09;存储数据&#xff0c;保存…

飞致云与上海吉谛达成战略合作,获得Gitea企业版中国大陆地区独家代理权

2023年12月13日&#xff0c;中国领先的开源软件提供商FIT2CLOUD飞致云宣布与上海吉谛科技有限公司&#xff08;以下简称为上海吉谛&#xff09;正式达成战略合作&#xff0c;FIT2CLOUD飞致云获得上海吉谛旗下代码托管平台Gitea企业版中国大陆地区独家代理权。 Gitea项目&…

Github 2023-12-14开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-14统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量非开发语言项目5TypeScript项目2JavaScript项目1Jupyter Notebook项目1PHP项目1 基于项目的学习 创建周期&a…

[ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证

文章目录 一、前言二、在 Azure Portal 中创建 VM三、验证已创建的虚拟机资源3.1 方法一&#xff1a;在虚拟机服务中查看验证3.1 方法二&#xff1a;在资源组服务中查看验证 四、文末总结 一、前言 本文会开始创建新系列的专栏&#xff0c;专门更新 Azure 云实践相关的文章。 …

CAN 三: STM32 CAN相关寄存器介绍

1、寄存器列表&#xff08;F1/F4/F7&#xff09; 寄存器名称作用CAN_MCRCAN主控制寄存器主要负责CAN工作模式的配置CAN_BTR位时序寄存器用来设置分频/TBS1/TBS2/TSWJ等参数&#xff0c;设置测试模式CAN_(T/R)IxR标识符寄存器存放(待发送/接收)的报文ID、扩展ID、IDE位及RTR位C…

MySQL 报错 You can‘t specify target table for update in FROM clause解决办法

You can’t specify target table for update in FROM clause 其含义是&#xff1a;不能在同一表中查询的数据作为同一表的更新数 单独执行复合查询是正常的&#xff0c;如下&#xff1a; 但是当执行子查询删除命令时&#xff0c;报如下错误 DELETE FROM abpusers WHERE Id I…

loki 如何格式化日志

部署 grafana-loki 首先介绍一下如何部署 官方文档&#xff1a;部署 grafana-loki 部署命令 设置集群的存储类&#xff0c;如果有默认可以不设置设置命名空间 helm install loki oci://registry-1.docker.io/bitnamicharts/grafana-loki --set global.storageClasslocal -n …

改进YOLOv8注意力系列二:结合CBAM、Coordinate Attention、deformable_LKA_Attention可变形大核注意力

改进YOLOv8注意力系列二:结合ACmix、Biformer、BAM注意力机制 代码CBAM注意力Coordinate Attention坐标注意力deformable_LKA_Attention可变形大核注意力加入方法各种yaml加入结构本文提供了改进 YOLOv8注意力系列包含不同的注意力机制以及多种加入方式,在本文中具有完整的代…

Linux查看端口使用情况

1、netstat命令 netstat命令用于显示与网络相关的信息&#xff0c;包括正在使用的端口。 netstat -tuln 其中&#xff0c;-t选项表示显示TCP连接&#xff0c;-u选项表示显示UDP连接&#xff0c;-l选项表示仅显示监听状态的连接&#xff0c;-n选项表示显示数字格式的IP地址和端口…

在Linux上安装配置Nginx高性能Web服务器

1 前言 Nginx是一个高性能的开源Web服务器&#xff0c;同时也可以作为反向代理服务器、负载均衡器、HTTP缓存以及作为一个邮件代理服务器。它以其出色的性能和灵活性而闻名&#xff0c;被广泛用于处理高流量的网站和应用程序。本文将介绍在Linux环境中安装Nginx的步骤&#xf…

设计模式之开篇

在软件开发的世界里&#xff0c;设计模式有如一本精妙的工程艺术指导准则&#xff0c;为我们提供了解决常见问题的优雅实现方案。然而&#xff0c;有些程序员可能会认为设计模式太过繁琐&#xff0c;一个简单的 if/else 语句就能解决问题&#xff0c;何必费心去学习这些看似复杂…

利用python批量压缩图教程:如何轻松减小图片大小

在日常的编程工作中&#xff0c;我们经常需要处理图像&#xff0c;例如上传、下载、显示、编辑等。有时候&#xff0c;我们需要对图像进行压缩&#xff0c;以减少占用的空间和带宽&#xff0c;提高加载速度和用户体验。那么&#xff0c;如何用Python来实现图像压缩呢&#xff1…

Linux_Ubuntu 系统入门

Ubuntu 系统是和 Windows 系统一样的大型桌面操作系统&#xff0c;因此功能非常强大。 本节的目的是掌握后续嵌入式开发所需的 Ubuntu 基本技能&#xff0c;比如系统的基本设置、常用的 shell 命令、vim 编译器的基本操作等等…… Ubuntu 的图形化界面操作和 Windows 下基本一致…

leetcode(平衡二叉树)

https://leetcode.cn/problems/balanced-binary-tree/description/ 这题的思路分成子问题就是计算左右子树的高度然后相减看看是不是大于1的就可以了&#xff0c;所以代码如下 int _isBalanced(struct TreeNode* root) {if(root NULL){return 0;}int leftdepth _isBalanced(…