bthread是一个M:N线程库,是brpc的核心组件。bthread实现了用户态上下文切换,主要有2个目标,一是降低编码难度,业务层可使用同步编程模式;二是在多核系统上取得更好的扩展性和局部性,提供更低的延时,更高的cpu利用率。
bthread和协程
谈到bthread,就不得不提协程。首先要强调的一点是,bthread不是协程。一般上我们说的协程的概念是M:1线程库,多个协程跑在一个底层pthread上,一个协程阻塞就会导致协程所在的pthread阻塞,进而该pthread上的其他协程都无法被调度执行。因此协程中不能执行长时间阻塞操作,只能搭配异步I/O,典型的使用场景是http server,这也是golang这种对协程支持较好的语言作为web server开发语言选型越来越流行的一个因素。brpc常用于大规模在线服务的后端server,特点是任务执行时间不确定,常出现少量任务延迟高的情况,在协程模型下就会导致卡住进程造成糟糕的性能表现。与协程最大的区别是,一个bthread被卡住不会影响其他bthread调度,原因是bthread基于butex实现了一套同步机制,这个在后文针对butex的源码分析中会做详细解剖。
为什么要读bthread源码
1、加深对系统库乃至底层操作系统原理的理解,知其然更知其所以然。
正如多数开发者都有使用pthread库的经历,然而对pthread内部实现细节有深入了解的却寥寥无几,brpc的开发者往往没有对bthread内部实现细节进行深挖。诚然对于现代软件体量膨胀的现状不可能要求开发者对自己程序中使用的所有组件内部实现都了如指掌,然而底层系统或者lib中有很多设计理念和实现细节值得深挖,一方面遇到一些疑难杂症时可以做到有的放矢不至于两眼抓瞎,另一方面计算机系统很多理念是通用的,深入了解已经在工程实践中验证过正确性的实现对自己将来开发类似功能的程序有显著帮助。bthread建立了一整套上下文切换、线程调度、同步原语、线程局部存储机制,而代码控制在2W行以内,对bthread进行源码级别的深入剖析,能加深操作系统基础概念的理解,拓展技术深度。笔者在读完bthread代码后,对很多原本模糊不清的概念有了深入理解,比如很多教科书和网上资料会谈