前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >brpc的bthread解读

brpc的bthread解读

原创
作者头像
mariolu
修改于 2020-04-06 17:23:59
修改于 2020-04-06 17:23:59
3.6K3
举报

一、Bthread的简单使用

代码语言:c++
AI代码解释
复制
std::vector<bthread_t> bids;
for (int i = 0; i < FLAGS_thread_num; ++i) {
    if (bthread_start_background(&bids[i], NULL, myfunc, &myarg) != 0) {
        LOG(ERROR) << "Fail to create bthread";
        return -1;
     }
}

for (int i = 0; i < FLAGS_thread_num; ++i) {
     bthread_join(bids[i], NULL);
}
  • bthread_start_background 相当于pthread_create,此外还有bthread_start_urgent,这个urgent函数用于代码更需要紧急执行的场景,他会把旧的线程置入调度队列里。
  • bthread_join 相当于pthread_join吗

二、bthread的原理

bthread是brpc使用的M:N线程库,M个bthread会映射至N个pthread。

在我们调用一次bthread_start_background / bthread_start_urgent会依次触发TaskControl和TaskGroup的相应接口。bthread主要的类有两个TaskControl和TaskGroup,下面就来探究下TaskControl和TaskGroup如何实现M:N的线程模型。

图1、TaskControl和TaskGroup的调用链
图1、TaskControl和TaskGroup的调用链

2.1、 bthread进入TaskControl

首先Task Control使用单例模式。

get_or_new_task_control 获取到Task Control实例,并且确保了唯一Task Control的实例,在改函数中该实例严格的生成用atomic保证,并且使用内存memory_order_consume保证了代码顺序不被编译器优化,确保了在多线程环境下的执行顺序。

2.2、 TaskControl

TaskControl采用单例模式,对TaskGroup进行管理。

  • Task Control可以创建多个Task Group,这里用concurrency并发度表示多个Task Gruop。代码中检验是否的TaskControl创建并初始化成功的依据是判butil::atomic<int> _concurrency是一个有效的值。默认个数是9
  • Task Control还会创建一个定时器线程。brpc采用condition_variable的唤醒方式+墙上时钟+小顶堆的方式实现其定时器。
  • Timerthread负责执行定时器唤醒并执行定时任务

那么Task Control管理了什么?以下图示是task control的接口:

接口主要分为两大类:一类是创建并管理TaskGroup,一类是统计TaskGroup相关的数据:

  • 创建管理Task Group,包括add_worker,choose_one_group,stop_and_join,delete_task_group
  • 统计taskgroup的数据包括get_cumulated_worker_time,get_cumulated_switch_count,get_cumulated_signal_count,print_rq_sizes_in_the_tc
  • steal_worker(TaskGroup在自身队列中没有任务情况下,抢占其他task group的内核pthread资源)
  • signal_task,唤醒没有任务在等待的TaskGroup处理任务
  • TaskControl管辖的Pthread之外的Pthread创建的Bthread,由TaskControl 随机选一个TaskGroup进行bthread投递。
图2 TaskControl的接口
图2 TaskControl的接口

2.3、TaskGroup

  • TaskGroup则1:1对应pthread
  • 他是1:N的 bthread调度器。一个TaskGroup是一个pthread,但是可以管理多个归属于这个TaskGroup的所有bthread Task,
  • 一个task_group维护者一个run_queue和一个remote_queue。Remote_queue:用于存放非TaskControl中线程创建的Bthread

备份二级队列, 向队列中提交不在btrhead中创建的任务

2.3.1 入口函数run_main_task()

TaskGroup::run_main_task() 这个是TaskGroup的main入口。

代码语言:c++
AI代码解释
复制
while(Wait_task()) {
        //按照顺序先从自身的run_queue,然后去remote_queue找任务执行,或者steal的方式调度任务
        TaskGroup::sched_to(&dummy,tid); 
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
3 条评论
热度
最新
你好,请问文章中TaskControl和TaskGroup的调用链的调用链是什么软件生成的
你好,请问文章中TaskControl和TaskGroup的调用链的调用链是什么软件生成的
22点赞举报
这是官方资料截图的
这是官方资料截图的
回复回复点赞举报
11, 非常感谢
11, 非常感谢
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
bthread源码剖析(一): 基本概念与TaskControl初始化
如果你使用过brpc,那么对bthread应该并不陌生。毫不夸张地说,brpc的精华全在bthread上了。bthread可以理解为“协程”,尽管官方文档的FAQ中,并不称之为协程。见:
果冻虾仁
2021/12/08
1.3K0
bthread源码剖析(一): 基本概念与TaskControl初始化
bthread源码剖析(二): 工作窃取与TaskGroup的run_main_task()
上一篇文章,介绍了TaskControl(简称TC)的初始化逻辑、worker的基本概念,并引出了TaskGroup(简称TG)的主要函数:run_main_task()。在谈run_main_task()之前,我们先看一下TG的几个主要成员。
果冻虾仁
2021/12/08
9280
bthread源码剖析(四): 通过ParkingLot实现Worker间任务状态同步
通过之前的文章我们知道TaskGroup(以下简称TG)是在死循环等待任务,然后切换栈去执行任务。在当前TG没有任务的时候会进行“工作窃取”窃取其他TG的任务。在没有任务的时候TG会“休眠”,当任务出现的时候被唤醒然后消费。
果冻虾仁
2021/12/08
1.3K0
brpc小课堂:有界队列BoundedQueue
brpc实现了一个“有界队列”的类模板BoundedQueue。先说一下什么是有界队列。 所谓有界队列表示的就是一个队列其中的容量是有限的(固定的),不能动态扩容的队列。这种听起来没有vector那种自动扩容能力的容器,主要还是全面为了性能考虑的。一般也是用作生产者和消费者模式,当队列容量已满的时候,一般就表示超过了这个队列的最大吞吐能力,故而拒绝加入新的任务。
果冻虾仁
2021/12/30
7280
brpc小课堂:有界队列BoundedQueue
《C++并发编程实战》读书笔记(6):高级线程管理、并行算法函数、测试与除错
大多数程序中并不方便给每个任务分配单独的线程,但仍可通过线程池来充分利用可调配的并发算力:将可同时执行的任务提交到线程池,放入任务队列中等待,工作线程循环地领取并执行任务。
C语言与CPP编程
2023/09/19
3680
《C++并发编程实战》读书笔记(6):高级线程管理、并行算法函数、测试与除错
SRS开源直播服务 - StateThreads微线程框架学习
SRS是一个开源流媒体服务器,在目前大火的直播行业中较多的被使用。笔者作为直播行业的后台开发,对SRS的学习必不可少,本文主要讲解SRS底层使用的微线程开源框架StateThreads。
chengkunkou
2018/08/28
7.4K2
阿里、字节:一套高效的iOS面试题( 多线程 GCD底层原理篇)
dispatch_group_create() + dispatch_group_wait()
会写bug的程序员
2020/06/18
4.8K0
阿里、字节:一套高效的iOS面试题( 多线程 GCD底层原理篇)
brpc中的定时任务使用介绍
众所周知,一个RPC框架除了处理网络请求以外,还有一类任务就是定时任务。所以RPC框架一般都直接提供定时任务的功能。今天我就来聊一下brpc中的定时任务。
果冻虾仁
2021/12/08
1.7K0
brpc中的定时任务使用介绍
源码阅读之 pond
前面的是默认值;后面的是错误定义。这是个好习惯,将系统可能的错误枚举地、显示的定义、罗列,方便调用者判断错误,或包装转发错误。
charmer
2025/03/26
400
Java多线程案例
阻塞队列的一个典型应用场景就是 “生产者消费者模型”. 这是一种非常典型的开发模型
用户9645905
2023/10/25
2070
JavaEE 【知识改变命运】05 多线程(4)
在这个模型中,服务器A要时刻感应到服务器B,在调用的过程中双方都要知道对方需要调用的参数和调用方式 ,在ABC整个调用的链路中秒如果其中一个出现了问题,就会影响整个业务执行
用户11319080
2025/01/03
890
JavaEE 【知识改变命运】05 多线程(4)
【Java并发编程三】多线程案例(手撕单例模式,阻塞队列,定时器,线程池)
单例模式具体的实现方式 , 有非常多种,本篇文章主要讲述“饿汉模式”和“懒汉模式”两种方法。
小皮侠
2024/10/17
1570
【Linux】线程池详解及其基本架构与单例模式实现
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
用户11316056
2024/11/19
1480
【Linux】线程池详解及其基本架构与单例模式实现
Java高并发与多线程网络编程
当JVM启动时,会创建一个非守护线程 main,作为整个程序的入口,以及多个与系统相关的守护线程。
devi
2021/08/19
1.4K0
Java高并发与多线程网络编程
Linux线程-生产消费模型和线程池
注:互斥关系保证的是数据的访问正常,而同步关系是为了让多线程(生产和消费者)之间协同起来
用户9645905
2022/11/30
3.3K0
Linux线程-生产消费模型和线程池
Linux性能调优之使用BPF工具观测CPU性能指标
喜欢文字的人,大多敏感且心软,忽然不快乐忽然被回忆揪住心脏忽然沉默到泪流。或许是内心孤独的缘故,轻易便可从他人的故事里看到自己的影子所以,悲伤总要比别人多一半。
山河已无恙
2024/10/21
4950
Linux性能调优之使用BPF工具观测CPU性能指标
让事件飞 ——Linux eventfd 原理与实践
目前越来越多的应用程序采用事件驱动的方式实现功能,如何高效地利用系统资源实现通知的管理和送达就愈发变得重要起来。在Linux系统中,eventfd是一个用来通知事件的文件描述符,timerfd是的定时器事件的文件描述符。二者都是内核向用户空间的应用发送通知的机制,可以有效地被用来实现用户空间的事件/通知驱动的应用程序。
李海彬
2018/07/31
6.1K0
让事件飞 ——Linux eventfd 原理与实践
glibc nptl库pthread_mutex_lock和pthread_mutex_unlock浅析
    futex全称是fast user-space locking,也就是快速用户空间锁,在linux下使用C语言写多线程程序时,在需要线程同步的地方会经常使用pthread_mutex_lock()函数对临界区进行加锁,如果加锁失败线程就会挂起,这就是互斥锁。但是pthread_mutex_lock并不是立即进行系统调用,而是首先在用户态进行CAS操作,判断其它线程是否已经获取了锁,如果锁被其它线程获取了,再进行系统调用sys_futex(),将当前线程挂起。futex可以用在多线程程序中,也可以用在多进程程序中。互斥变量是一个32位的值。
用户4415180
2022/06/23
1.9K0
Rust Async: smol源码分析-Executor篇
本文来自知乎:https://zhuanlan.zhihu.com/p/137353103
MikeLoveRust
2020/05/14
1K0
Rust Async: smol源码分析-Executor篇
推荐:多线程的实现方式及经典示例
iOS中实现多线程的技术方案 pthread 实现多线程操作 代码实现: void * run(void *param) { for (NSInteger i = 0; i < 1000; i
春哥大魔王
2018/04/16
1.2K0
推荐:多线程的实现方式及经典示例
推荐阅读
相关推荐
bthread源码剖析(一): 基本概念与TaskControl初始化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档