當使用多執行緒時,可能存在同時訪問乙個變數,導致變數被汙染問題,所以需要通過程式設計克服這個問題。
採用多個執行緒,分別記數,然後檢視最終計算結果,**如下:
#include
#include
#include
//計數全域性變數
long cnt =0;
//計數程式
void
counter()
}int
main
(int argc,
char
* ar**)
//等待操作
for(
auto
& th : threads)
th.join()
; clock_t finish =
clock()
; std::cout <<
"期望結果:"
<<
100*
100000
<< std::endl;
std::cout <<
"實際結果:"
<< cnt << std::endl;
std::cout <<
"duration:"
<< finish - start <<
"ms"
<< std::endl;
return0;
}
執行結果:
期望結果:10000000
實際結果:
9400000
duration:
104ms
可以看出,存在資料丟失問題,其原因是同時訪問變數cnt導致,所以,需要採用程式設計方法,保證每次只能有乙個程式訪問cnt變數。
在 c++11中,mutex是標準庫, 呼叫#include < mutex>標頭檔案呼叫,其主要類為std::mutex
,其成員函式包括
示例**如下:
#include
#include
#include
#include
//新增互斥變數標頭檔案
//建立互斥變數鎖
std::mutex my_mutex;
//計數全域性變數
long cnt =0;
//計數程式
void
counter()
}int
main
(int argc,
char
* ar**)
//等待操作
for(
auto
& th : threads)
th.join()
; clock_t finish =
clock()
; std::cout <<
"期望結果:"
<<
100*
100000
<< std::endl;
std::cout <<
"實際結果:"
<< cnt << std::endl;
std::cout <<
"duration:"
<< finish - start <<
"ms"
<< std::endl;
return0;
}
計算結果如下:
期望結果:10000000
實際結果:
10000000
duration:
456ms
採用互斥變數後,能真確計算,但是時間從104ms,變到456ms。
atomic是c++標準程式庫中的乙個標頭檔案,定義了c++11標準中的一些表示執行緒、併發控制時原子操作的類與方法等。此標頭檔案主要宣告了兩大類原子物件:std::atomic和std::atomic_flag,另外還宣告了一套c風格的原子型別和與c相容的原子操作的函式。在多執行緒併發執行時,原子操作是執行緒不會被打斷的執行片段。一些程式設計更為注重效能和效率,需要開發lock-free的演算法和資料結構,這就需要更為底層的原子操作與原子型別。原子型別物件的主要特點就是從不同執行緒併發訪問是良性(well-defined)行為,不會導致競爭危害。與之相反,不做適當控制就併發訪問非原子物件則會導致未定義(undifined)行為。
示例**:
#include
#include
#include
#include
//新增原子操作標頭檔案
//建立原子操作變數
std::atomic_long cnt;
//計數程式
void
counter()
}int
main
(int argc,
char
* ar**)
//等待操作
for(
auto
& th : threads)
th.join()
; clock_t finish =
clock()
; std::cout <<
"期望結果:"
<<
100*
100000
<< std::endl;
std::cout <<
"實際結果:"
<< cnt << std::endl;
std::cout <<
"duration:"
<< finish - start <<
"ms"
<< std::endl;
return0;
}
執行結果:
期望結果:10000000
實際結果:
10000000
duration:
228ms
結果表明,採用原子變數能保證運算結果正確,且能相對於互斥變數mutex,運算速度明顯提高。 多執行緒 執行緒安全
原因 當多個執行緒同時共享,同乙個全域性變數或靜態變數。做寫的操作時,可能發生資料衝突問題,也就是執行緒安全問題。但是做讀操作是不會發生資料衝突問題。解決方案 方式一 內建鎖synchronized synchronized保證執行緒原子性,當執行緒進入方法的時候,自動獲取鎖,一旦鎖被其它執行緒獲取...
多執行緒 執行緒安全
public class unsafethread t.start while thread.activecount 1 system.out.println sum 1 從主記憶體中講sum變數複製到執行緒的工作記憶體 2 在工作記憶體中修改變數 1操作 3 將sum變數從執行緒的工作記憶體寫回到...
多執行緒 執行緒安全
執行緒安全 多個執行流對臨界資源的爭搶訪問,但是不會出現資料二義性 執行緒安全的實現 同步 通過條件判斷保證對臨界資源訪問的合理性 互斥 通過同一時間對臨界資源訪問的唯一性實現臨界資源訪問的安全性 互斥鎖實現的原理 互斥鎖本身是乙個只有0 1的計數器,描述了乙個臨界資源當前的訪問狀態,所有執行流在訪...