多執行緒技術讓多個處理器機器,多核機器和集群系統執行更快。因為多執行緒模型與生俱來的優勢可以使這些機器或者系統實現真實地的併發執行。但多執行緒在帶來便利的同時,也引入一些問題。執行緒主要由控制流程和資源使用兩部分構成,因此乙個不得不面對的問題就是對共享資源的訪問。為了確保資源得到正確的使用,開發人員在設計編寫程式時需要考慮避免競爭條件和死鎖,需要更多地考慮使用執行緒互斥變數。
執行緒安全 (thread-safe) 的函式就是乙個在**層面解決上述問題比較好的方法,也成為多執行緒程式設計中的乙個關鍵技術。如果在多執行緒併發執行的情況下,乙個函式可以安全地被多個執行緒併發呼叫,可以說這個函式是執行緒安全的。反之,則稱之為「非執行緒安全」函式。注意:在單執行緒環境下,沒有「執行緒安全」和「非執行緒安全」的概念。因此,乙個執行緒安全的函式允許任意地被任意的執行緒呼叫,程式開發人員可以把主要的精力在自己的程式邏輯上,在呼叫時不需要考慮鎖和資源訪問控制,這在很大程度上會降低軟體的死鎖故障和資源併發訪問衝突的機率。所以,開發人員應盡可能編寫和呼叫執行緒安全函式。
判斷乙個函式是否執行緒安全不是一件很容易的事情。但是讀者可以通過下面這幾條確定乙個函式是執行緒不安全的。
因此在編寫執行緒安全函式時,要注意兩點:
舉個例子(參考 例子 1
),下面的這個函式 sum()是執行緒安全的,因為函式不依賴任何全域性變數。
int sum(int i, int j)
但如果按下面的方法修改,sum()就不再是執行緒安全的,因為它呼叫的函式 inc_sum_counter()不是執行緒安全的,該函式訪問了未加鎖保護的全域性變數 sum_invoke_counter。這樣的**在單執行緒環境下不會有任何問題,但如果呼叫者是在多執行緒環境中,因為 sum()有可能被併發呼叫,所以全域性變數 sum_invoke_counter很有可能被併發修改,從而導致計數出錯。
static int sum_invoke_counter = 0;void inc_sum_counter(int i, int j)
int sum(int i, int j)
我們可通過對全域性變數 sum_invoke_counter新增鎖保護,使得 inc_sum_counter()成為乙個執行緒安全的函式。
static int sum_invoke_counter = 0;static pthread_mutex_t sum_invoke_counter_lock = pthread_mutex_initializer;
void inc_sum_counter(int i, int j)
int sum(int i, int j)
現在 , sum()和 inc_sum_counter()都成為了執行緒安全函式。在多執行緒環境下,sum()可以被併發的呼叫,但所有訪問 inc_sum_counter()執行緒都會在互斥鎖 sum_invoke_counter_lock上排隊,任何乙個時刻都只允許乙個執行緒修改 sum_invoke_counter,所以 inc_sum_counter()就是現成安全的。
除了執行緒安全還有乙個很重要的概念就是可重入(re-entrant),所謂可重入,即:當乙個函式在被乙個執行緒呼叫時,可以允許被其他執行緒再呼叫。顯而易見,如果乙個函式是可重入的,那麼它肯定是執行緒安全的。但反之未然,乙個函式是執行緒安全的,卻未必是可重入的。程式開發人員應該盡量編寫可重入的函式。
乙個函式想要成為可重入的函式,必須滿足下列要求:
對比前面的要求,例子 1的 sum()函式是可重入的,因此也是執行緒安全的。例子 3中的 inc_sum_counter()函式雖然是執行緒安全的,但是由於使用了靜態變數和鎖,所以它是不可重入的。因為 例子 3中的 sum()使用了不可重入函式 inc_sum_counter(), 它也是不可重入的。
可重入和執行緒安全
執行緒安全這個詞對我來說已經不是很陌生的了,但是遇到乙個叫做可重入函式的詞,它給我的感覺和執行緒安全是這麼的相近,但既然拿出來了,肯定是有區別的,下面就說說他們之間的區別和聯絡。要先解釋這兩個詞語才行。執行緒安全 似乎是在牛客網刷題的時候看到乙個正確的選項說的是,執行緒安全問題都是由全域性變數及靜態...
可重入和執行緒安全
綜觀整個文件,術語可重入和執行緒安全總是被用來標記類和函式,表明他們如何被用在多執行緒程式中。乙個執行緒安全的函式能被多個執行緒同時呼叫,甚至在這些呼叫使用共享資料時,因為所有對共享資料的引用是序列進行的。乙個可重入的函式也能被多個執行緒同時呼叫,但前提是每個呼叫只使用它們自己的資料。所以,乙個執行...
可重入和執行緒安全
1 定義 1 執行緒安全 多個執行緒同時執行一段 不會造成資源的衝突,不會產生錯誤的結果,那麼這段 是執行緒安全的。2 可重入 多個執行流反覆執行一段 其結果不會發生改變。2 條件 1 常見執行緒安全滿足的條件 2 常見可重入函式滿足的條件 3 區別 可重入的函式必定是執行緒安全的,而執行緒安全的函...