BThread作为一个高效、易用的C++ 风格的并发编程库(Concurrency Library),是新一代的轻量级协程库。BThread提供了BThread、BThread协程、BThread Task、BThread切换原理、线程切换等丰富的功能,为多线程编程提供了很多便捷的方式和解决方案。本篇文章将从多个方面对BThread做详细的阐述。
一、BThread 原理
BThread是一个管理着其它BThread协程或者线程、并通过协同运行实现调度的对象。BThread是并发编程中核心的参与者。BThread通过运用协程模型,以轻量级协程的方式,切换执行任务。BThread采用的是单线程的执行模式。
实现原理的核心,是封装一个协程和线程任务重用的模板框架,通过一些底层的工具函数,使得上层实现代码看上去和一个单纯的运行在一个线程里面的协程调度差不多。BThread做到的核心是:协程的切换、框架的独立性和通用性,可以支持异步IO和信号函数调用。
二、BThread的 Task 内部还有BThread
BThread的 Task 内部可以创建一个BThread来执行,这也就意味着一个BThread的可运行状态,可以加入到另一个BThread的任务作为一个Task执行。这样一来,就使得一个BThread实例可以掌控多个协程线程的执行,且掌控的方式是递归的。BThread的 Task 能够通过yield进行权重轮询,从而在Busy Wait状态中省去了睡眠期间的时间。
示例代码:
#include
#include "bthread.h"
void *my_routine(void *arg)
{
while(1){
printf("Hello master\n");
sleep(2);
bthread_yield();
}
return NULL;
}
void *my_routine2(void *arg)
{
while(1){
printf("Hello worker\n");
sleep(2);
bthread_yield();
}
return NULL;
}
int main(int argc, char *argv[])
{
bthread_t bk_worker;
bthread_t bk_master;
bthread_create(&bk_master, NULL, my_routine, NULL);
bthread_create(&bk_worker, NULL, my_routine2, NULL);
bthread_join(bk_master, NULL);
bthread_join(bk_worker, NULL);
return 0;
}
三、BThread协程
BThread库中使用的协程是基于轻量线程,而常规线程是重量级的,BThread协程能够让线程切换速度更快。协程的调度是由BThread来进行,而不是如常规的线程切换一样由系统调度(OS 线程)。这种方式可以让协程的切换速度非常快。
BThread协程的底层通过一个上下文切换函数bthread_jump_ctx(void *old_ctx, void *new_ctx, int val)来实现。这个函数是一个汇编实现,使得BThread能够直接在代码层次上管理协程以及进行协程切换。在底层的跳转函数bthread_jump_ctx中,会做一些列协程和线程对象切换的操作。
四、BThread 切换原理
BThread的协程利用协程模型,进行协同运行实现调度的对象。BThread通过运用协程模型,以轻量级协程的方式,切换执行任务。在BThread协程中,通过yield和resume方式,实现协程调度与执行。调用bthread_yield函数可以将当前的上下文切换到下一个协程上。
示例代码:
#include
#include "bthread.h"
void *my_routine1(void *arg)
{
while(1){
printf("Hello 1\n");
bthread_yield();
}
return NULL;
}
void *my_routine2(void *arg)
{
while(1){
printf("Hello 2\n");
bthread_yield();
}
return NULL;
}
void *my_routine3(void *arg)
{
while(1){
printf("Hello 3\n");
bthread_yield();
}
return NULL;
}
int main(int argc, char *argv[])
{
bthread_t bk[3];
bthread_create(&bk[0], NULL, my_routine1, NULL);
bthread_create(&bk[1], NULL, my_routine2, NULL);
bthread_create(&bk[2], NULL, my_routine3, NULL);
while(1){
int i;
for (i = 0;i < 3;i++){
bthread_resume(bk[i]);
}
sleep(2);
}
return 0;
}
五、BThread 线程切换
BThread 线程切换是BThread库中非常重要的一个功能。在线程执行中,经常需要暂停执行并切换到其他的线程上,这种机制就称之为线程切换。这种切换是多线程编程的核心。BThread库中的线程切换,是通过协程模型来实现的。
六、BThread源码分析
BThread是一个完整的C++ 风格的并发编程库,其源代码也具有很高的可读性、可学习性。在BThread源代码当中,有非常丰富的实践经验。
七、BThread和pthread
BThread的建立一定程度上是为了解决PThread文档的”短版”文档而生的。BThread在增加更多的功能的同时,尽量避免了PThread约束性的问题。BThread库可以很好地保留 “from zero to hero”的开发模式,同时对于新手也无需掌握过多的技能内容。
八、BThread ID
BThread ID是一个十分重要的概念。每个BThread实体都有自己的BThread ID,能够唯一地标识其实体。我们可以通过函数bthread_self()获得BThread ID。
九、BThread Condition
BThread Condition是是一种锁机制。通过对条件变量的监听,控制多线程对共享数据的访问。BThread中提供了丰富的锁机制,以帮助程序员更好地处理多线程之间的同步、协同问题。
示例代码:
#include
#include
#include
#include "bthread.h"
bthread_mutex_t lock;
bthread_cond_t cond;
int g_count = 0;
void *my_routine1(void *arg)
{
while(1) {
bthread_mutex_lock(&lock);
g_count++;
printf("count=%d\n", g_count);
if (g_count == 5)
{
bthread_cond_signal(&cond);
printf("condition changed.\n");
}
bthread_mutex_unlock(&lock);
usleep(500 * 1000);
}
return NULL;
}
void *my_routine2(void *arg)
{
bthread_mutex_lock(&lock);
while (1)
{
bthread_cond_wait(&cond, &lock);
printf("con4signaled.\n");
bthread_mutex_unlock(&lock);
exit(0);
}
return NULL;
}
int main(int argc, char *argv[])
{
bthread_t bk[2];
bthread_mutex_init(&lock, NULL);
bthread_cond_init(&cond, NULL);
bthread_create(&bk[0], NULL, my_routine1, NULL);
bthread_create(&bk[1], NULL, my_routine2, NULL);
bthread_join(bk[0], NULL);
bthread_join(bk[1], NULL);
bthread_cond_destroy(&cond);
bthread_mutex_destroy(&lock);
return 0;
}
总结
通过本篇文章,我们对BThread的原理、BThread的Task内部还有BThread、BThread协程、BThread切换原理、线程切换、BThread源码分析、BThread和pthread、BThread ID、BThread Condition等多个方面做了详细的阐述。BThread不仅提供了方便快捷的解决方案,而且BThread的源码非常简洁易懂,通过学习BThread的核心设计原理和实践经验,我们可以更好地应对多线程编程中的挑战。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/198999.html