問題背景:在工做中遇到過一個問題,就是在兩個線程同時調用同一個函數的時候,究竟是應該在這個函數的內部什麼處理上加上互斥。緣由又是什麼?函數
爲了調查這個問題,我決定從如下三方面調查spa
1.線程中函數的調用線程
2.同一個進程中的兩個線程調用同一個處理函數指針
3.兩個不一樣進程中的兩個線程調用同一個處理函數隊列
1.線程中函數的調用
每一個進程都會有本身的虛擬地址空間,同一個進程中的每一個線程都會在這個虛擬空間中,並被分配相應的資源。
線程中的函數實體是在內存中,而函數中的局部變量則會一次被push到棧中。
若是是A函數調用B函數,則會先將A函數的參數和局部變量push到隊列中,再將B函數的參數和局部變量push到隊列中
具體以下(參數是以從右到左壓入棧中,__stdcall與__cdecl調用約定都是這麼處理的):
void fun(param1, param2,. param3....paramN)
{
value1;
value2;
...
valueN;
}
若是執行上面的函數在棧中會這樣變化進程
1:將fun函數的入力參數從右到左依次壓入到棧中。ip
2:將fun函數的指針壓入棧中內存
3:將ebp,ebx等寄存器入棧保存
4:在棧中依次爲各個變量分配空間資源
執行後的處理:get
1.釋放變量空間
2.彈出個寄存器
3.ret,彈出eip,返回主調方代碼
4.釋放參數空間
2.兩個線程調用同一個函數
兩個線程中的函數的局部變量因爲是保存在不一樣的線程中,所以不須要進行互斥處理
3.兩個不一樣進程中的兩個線程調用同一個處理函數
一樣,兩個線程中的函數的局部變量因爲是保存在不一樣的線程中,所以不須要進行互斥處理
結論:
所以須要互斥處理的,通常是函數中有
全局變量,有動態申請的空間,有靜態局部變量,有須要進程數據循環發送之類的操做須要進行互斥處理