如果使用多執行緒,那麼幾乎都會用到全域性變數,這時初始化全域性變數的技巧就很重要了。
通常初始化全域性變數時就是像下面這樣的,先判斷是否已經初始化過了,然後才去初始化。在單執行緒場景下,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...