首先宣告,此帖為錯誤帖,希望大家能作為反例來看。
希望大家能指正
當時,就是因為加入的是單執行緒執行時庫,導致new和delete操作出錯。後來,在看書的過程中,才知道,windows中,堆是屬於程序的,當多個執行緒對堆進行操作時,是需要加鎖的,如果匯入的是多執行緒執行時庫,那麼,在new和delete時,是加鎖來操作的。以後,我將向大家介紹windows的記憶體管理機制。
這段時間正在做乙個模組,總是出錯,提示指令引用的記憶體不能為「read」或「written」。
逐個排查錯誤,最終,發現是執行緒處理函式中的new語句那裡出了問題。
那麼,平時我們如下所用是安全的麼?
int *p = new int:
在單執行緒程式中,這樣用是安全的。多執行緒中呢?
you know,堆記憶體是多執行緒共用的。如果兩個執行緒同時對堆記憶體發出請求,問題就出現了。
你可以進行如下實驗:
#include
#include
dword winapi thrdproc(lpvoid lpparam);
int main()
for(i=0; i<8; i++)
printf("ok!\n");
return 0;
}dword winapi thrdproc(lpvoid lpparam)
}return 0;
}此實驗中,8個執行緒頻繁申請堆空間
接著,你可以再做乙個實驗
在上個實驗**中,delete pi;語句前,加一句printf("%d\n",*pi);,然後再執行一下,結果怎樣呢?
現在可以總結了:
如果多個執行緒同時請求堆記憶體操作,則會引發錯誤,因為執行緒共用堆記憶體。因此,第乙個實驗中,執行緒頻繁操作堆記憶體,引起衝突,導致錯誤出現。
那麼,平時我們直接用new等操作,為什麼不會出錯誤呢?你要知道,堆記憶體的分配及**,速度是相當快的。在第二個實驗中,執行緒不僅請求堆記憶體操作,還加了乙個printf。與new的執行速度相比,printf慢多了。這樣,就大大降低了衝突(執行緒對堆記憶體操作)概率。因此,第二個實驗執行時極少出錯,但不是絕對的安全。我們平時寫多執行緒的**,也正因為是這樣,所以,雖然存在隱患,但是卻很少發現它。
解決這個隱患,可以給堆記憶體加個全域性排斥鎖,或者臨界,只要執行緒對堆記憶體的操作(如new、delete,malloc、free),就要申請下
下面是用臨界做的測試:
#include
#include
critical_section g_lijie;
dword winapi threadfunc(lpvoid lpparam)
sleep(100);
}
單例模式是否執行緒安全
今天領導問了個問題說單例模式中,物件的變數是否是執行緒安全的。起初都不太確定,後來本著裝的目的,試了一下,結果是否定的。在多執行緒環境下,物件的成員變數是不安全的。package com.zhuyang.test public class singleton public static synchr...
簡單多執行緒是否安全判斷
1.明確哪些 是多執行緒執行的 2.明確共享資料 3.明確多執行緒執行 中哪些語句是操作共享資料.首先第一步,找到多執行緒執行的 也就是run方法裡面的 for int i 0 i 3 i 另外這裡用到了add方法,所以add也算 public void add int n 第二步,找到共享資料 b...
linux write 函式 是否是 執行緒安全的?
我做了兩個實驗 第乙個實驗,建立乙個本地檔案,然後用5個執行緒對這個檔案進行寫入,結果前面的寫入內容被後面的寫入內容覆蓋 對write函式加鎖之後結果就正常了,就似乎驗證了write函式是非執行緒安全的。第二個實驗,建立乙個客戶端的tcp socket,然後用5個執行緒對這個socket進行寫入 伺...