關於執行緒安全的學習

2021-06-20 12:42:41 字數 1267 閱讀 8200

背景:

最近在學習一套庫函式,因為涉及到資料的讀寫操作,所以庫函式提供了lock與unlock函式用於對寫操作進行保護。

需要保護的原因是函式庫沒有自己的執行緒,它們執行在庫函式呼叫者的執行緒中;

所以如果沒有保護機制,如果出現多個執行緒同時去做寫資料操作就會導致共享資料出錯;

這類函式也稱之為非執行緒安全的函式。

什麼是執行緒安全的?

1. 如果**會被多個執行緒同時呼叫,並且每次執行結果和單執行緒執行結果(執行結果可**)是一樣的,則稱之為執行緒安全的;

2. 程式所提供的介面對於執行緒來講是原子操作或多執行緒的切換不會導致介面執行結果存在二義性,也就是不用考慮同步問題;

如下面這篇博文,

物理上的原子操作無法做到;

現在的程式更多的採用加鎖保護機制來實現邏輯上的原子操作。

執行緒安全問題,通常是由於多個執行緒同時執行全域性變數或靜態變數的寫操作引起的;

這樣的程式通常稱之為非執行緒安全的程式;

對於非執行緒安全的程式,必須使用保護機制來保證執行緒同步,以此來保證程式執行的正確性。

多執行緒環境下常見的保護共享資源的方法有:

1. 對全域性變數使用mutex進行互斥訪問

pthread_mutex_lock(pthread_mutex_t* mutex);

pthread_mutex_unlock(pthread_mutex_t* mutex);

2. 對於讀寫資源使用read/write lock進行保護

pthread_rwlock_rdlock(rwlock);

pthread_rwlock_wrlock(rwlock);

pthread_rwlock_unlock(rwlock);

3. 使用條件變數,利用執行緒間共享的全域性變數進行執行緒同步的一種機制。

條件變數包括兩個動作:

1. 乙個執行緒等待條件變數的條件成立而掛起;

2. 另乙個執行緒使條件成立。

因為條件變數是多執行緒間共享的全域性變數,所以對這個變數本身必須使用mutex互斥鎖進行保護。

為了防止race condition,條件變數總是和乙個mutex一起使用。

注意:條件變數是執行緒間同步的一種機制;

而訊號量是執行緒間互斥訪問的一種機制。

鎖用到了,沒用好,可能會導致死鎖的發生;

不用鎖吧,就有race condition的可能。

煩人哪!

兩個問題:

1. 可重入函式的學習;

2. 如何使用鎖保護機制.

3. 關於條件變數要如何使用,後續再進行學習。

關於執行緒安全的小測試

起100個執行緒 1,迴圈100次檢視結果,正常來說應該是100對吧 public static int t 0 public static void main string args throws interruptedexception start 列印t的值 system.out.printl...

多執行緒學習06 執行緒安全

執行緒安全 互斥鎖 執行緒同步 多執行緒的安全隱患 1,資源共享 1塊資源可能會被多個執行緒共享,也就是多個執行緒可能會訪問同乙個資源 比如多個執行緒訪問同乙個物件 同乙個變數 同乙個檔案。2,當多個執行緒訪問同一塊資源時,很容易引發資料錯亂和資料安全問題 安全隱患解決 互斥鎖 互斥鎖使用格式 sy...

ATL中關於執行緒安全的優化

一直覺得自己的寫的乙個對臨近區呼叫的乙個封裝類很無敵,簡簡單單就搞定了乙個物件內部的執行緒同步,如果 有全域性變數的話,搞定多個物件的執行緒同步也不是很難,現在看了下atl的原始碼,原來和人家畢竟低等的 封裝一模一樣,慚愧啊。先看看人家對section的封裝吧,class ccomcriticals...