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/zh-hk/n/198999.html