什麼程式碼才是執行緒安全的
所以學習多執行緒程式設計最重要的不是學習API,而是理解什麼才是多執行緒安全的程式碼
從例子說起
#include <process.h> long global1 = 0;
volatile long global2 = 0; class MyClass
{
public:
MyClass() : m(0)
{
++m;
}
int fun(int v)
{
return m+v; //———–9
}
void set(int v)
{
m = v; //————-10
}
int m;
};
MyClass global_object;
//————-8unsigned int __stdcall thread_fun1(void *param)
{
static int static2 = 0;
static MyClass static_object; //——–6
int local1 = 0;
++local1; //——-1
++static2; //——-2
++global1; //——-3
++global2; //——-4
InterlockedIncrement(&global1); //——–5
local1 = global_object.fun(local1); //———-7
global_object.set(local1); //—————11
return 0;
}
unsigned
int __stdcall thread_fun2(void *param){
++global1; //——-3
++global2; //——-4
InterlockedIncrement(&global1); //——–5
global_object.set(1); //———–11
return 0;
} int main()
{
HANDLE thread1 = (HANDLE)_beginthreadex(0,0,&thread_fun1,0,0,0); //thread 1
HANDLE thread2 = (HANDLE)_beginthreadex(0,0,&thread_fun1,0,0,0); //thread 2
HANDLE thread3 = (HANDLE)_beginthreadex(0,0,&thread_fun2,0,0,0); //thread 3
WaitForSingleObject(thread1,INFINITE);
WaitForSingleObject(thread2,INFINITE);
WaitForSingleObject(thread3,INFINITE);
return 0;
}
1.區域性變數區域性使用是安全的
為什麼?因為每個thread 都有自己的執行堆疊,而區域性變數是生存在堆疊中,大家不干擾。
所以程式碼1
int local1;
++local1;
是安全的
2.全域性原生變數多執行緒讀寫是不安全的
全域性變數是在堆(heap)中
long global1 = 0;
++global2;
++這個操作其實分為兩部,一個是讀,另外一個是寫
mov ecx,global
add ecx,1
mov global,ecx
所以程式碼3處是不安全的
3.函式靜態變數多執行緒讀寫也是不安全的
道理同2
所以程式碼2處也是不安全的
4.volatile能保證全域性整形變數是多執行緒安全的麼
不能。
volatile僅僅是告誡compiler不要對這個變數作優化,每次都要從memory取數值,而不是從register
所以程式碼4也不是安全
5.InterlockedIncrement保證整型變數自增的原子性
所以程式碼5是安全的
6.function static object的初始化是多執行緒安全的麼
不是。
著名的Meyer Singleton其實不是執行緒安全的
Object & getInstance()
{
static Object o;
return o;
}
可能會造成多次初始化物件
所以程式碼6處是不安全的
7.在32機器上,4位元組整形一次assign是原子的
比如
i =10; //thread1
i=4; //thread2
不會導致i的值處於未知狀態,要麼是10要麼是4
寫好多執行緒安全的法寶就是封裝,使資料有保護的被訪問到
安全性:
區域性變數>成員變數>全域性變數
from:http://www.cppblog.com/ivenher/articles/15815.html
相關文章
- 程式執行緒新解:什麼是程式?什麼是執行緒?執行緒
- 什麼是執行緒安全和執行緒不安全執行緒
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- 什麼是程式(執行緒)同步執行緒
- 作業系統——執行緒與程式的區別與聯絡?什麼是執行緒安全?作業系統執行緒
- ArrayList 為什麼執行緒不安全執行緒
- 怎麼樣建立的執行緒才是安全的呢?帶著疑問看文章執行緒
- 什麼叫執行緒安全,舉例說明。執行緒
- 為什麼 Random.Shared 是執行緒安全的random執行緒
- 為什麼 Go map 和 slice 是非執行緒安全的?Go執行緒
- 為什麼?為什麼StringBuilder是執行緒不安全的?UI執行緒
- 執行緒與程式之間有什麼關係?Linux執行緒與程式有什麼區別?執行緒Linux
- 多執行緒-執行緒安全問題的產生原因分析以及同步程式碼塊的方式解決執行緒安全問題執行緒
- 碼農深耕 - 什麼樣的程式碼才是好程式碼?
- 什麼是程式、執行緒和協程?執行緒
- 舉例理解什麼是程式,執行緒執行緒
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- 什麼才是低程式碼開發?
- 併發程式設計之多執行緒執行緒安全程式設計執行緒
- 29-HashMap 為什麼是執行緒不安全的?HashMap執行緒
- 程式碼審查:從 ArrayList 說執行緒安全執行緒
- 【多執行緒與高併發】Java守護執行緒是什麼?什麼是Java的守護執行緒?執行緒Java
- 什麼是多執行緒?Python多執行緒有什麼優勢?執行緒Python
- JDK21的虛擬執行緒是什麼?和平臺執行緒什麼關係?JDK執行緒
- 【Java多執行緒】執行緒安全的集合Java執行緒
- 基礎才是重中之重~ConcurrentDictionary讓你的多執行緒程式碼更優美執行緒
- 執行緒3--執行緒安全執行緒
- 執行緒(一)——執行緒,執行緒池,Task概念+程式碼實踐執行緒
- 執行緒池管理(1)-為什麼需要執行緒池執行緒
- redis為什麼用單執行緒不用多執行緒Redis執行緒
- 執行緒安全和執行緒不安全理解執行緒
- 執行緒安全執行緒
- PHP的執行緒安全與非執行緒安全版本的區別PHP執行緒
- 多執行緒系列之 執行緒安全執行緒
- iOS 多執行緒之執行緒安全iOS執行緒
- iOS多執行緒之執行緒安全iOS執行緒
- Java執行緒(一):執行緒安全與不安全Java執行緒
- 程式設計思想之多執行緒與多程式(2):執行緒優先順序與執行緒安全程式設計執行緒