多執行緒如何優雅地初始化全域性變數?

2022-05-16 02:20:51 字數 1224 閱讀 5874

如果使用多執行緒,那麼幾乎都會用到全域性變數,這時初始化全域性變數的技巧就很重要了。

通常初始化全域性變數時就是像下面這樣的,先判斷是否已經初始化過了,然後才去初始化。在單執行緒場景下,lazy初始化(就是用到時才初始化)一般是下面這樣寫的,這沒問題。但是多執行緒場景下就不能這樣寫了,我們要先給random_is_initialized建立乙個mutex,否則這段**就問題大了。但是mutex也得初始化吧?初始化又要建立乙個mutex來保證前乙個mutex能正常初始化,這就陷入死迴圈了。

static int random_is_initialized = 0;

extern int initialize_random(); // 這個函式用來初始化全域性變數

int random_function()

... /* operations performed after initialization. */

}

posix提供了乙個函式pthread_once,很適合解決這種問題。它能保證只初始化一次全域性變數,而且執行緒安全,開發起來就很方便了。使用方法參考下面的實現。

#include static pthread_once_t random_is_initialized = pthread_once_init;

void initialize_random()

void *random_function(void *none)

int main()

sleep(100000); // 主線程不能退出

return 0;

}

編譯gcc -o test test.cpp -lpthread

你可能有疑問,為什麼不能在建立執行緒之前就初始化全域性變數?那樣的話不需要考慮什麼執行緒安全。確實是的。其他場景可能有更好的發揮餘地。

使用pthread_once肯定會好奇它是怎麼實現的,它的glibc實現在這裡。其實就是首個執行緒執行到pthread_once這裡了,其他執行緒就得等,直到首個執行緒執行完之後去喚醒其他執行緒。

**函式initialize_random中不應該有耗時的操作,一不小心可能永遠不會返回,這時其他的執行緒就會一直睡眠,這個程序就廢了。

未初始化全域性變數

未初始化全域性變數,這名字就很直白,就是 c 程式中定義成全域性作用域而又沒有初始化的變數,我們知道這種變數在程式執行後是被自動初始化為 全0 的。編譯器編譯的時候會將這類變數收集起來集中放置到 bss 段中,這個段只記錄了段長,沒有實際上的內容 全是0,沒必要儲存 在程式被裝載時作業系統會為它分配...

關於未初始化全域性變數

前幾天發現未初始化全域性變數一些特性,後來在一篇部落格上發現有人說過這個問題 這是原博文位址 blog.csdn.net liuqiaoyu080512 article details 8455652 然後結合原博文,自己又做了幾個實驗 以下算是自己實驗一遍以後的總結 首先,自己曾經以為未初化的全域...

C語言全域性變數的初始化

本意是想定義乙個全域性結構體變數,並設定其成變數的值。typedef struct a t a t a a.a 1 error expected asm or attribute before token a.b 2 error expected asm or attribute before to...