困擾了我很長時間的多線程訪問全局變量今天終於解決了,所以得記錄一下。。控制全局變量的方法很多,有信號量、臨界區等。。這里我記錄一個用臨界區控制訪問沖突的例子。非常好用。
#include <windows.h> #include <iostream> using namespace std; //首先做兩個線程,實現兩個線程間的同步 上次是利用互斥對象實現線程間的同步CreateMutex函數和事件對象間的同步CreateEvent函數,這次用關鍵代碼段(臨界區對象)來實現 DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets=100; CRITICAL_SECTION g_cs; //1.定義一個臨界區對象 void main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_cs); //2.初始化臨界對象 Sleep(4000); DeleteCriticalSection(&g_cs); //3.當函數要結束的時候釋放所有沒有被擁有的臨界區對象相關的成員 } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); //4.判斷是否有線程在訪問公共資源,如果有線程正在訪問就,不能執行下面的 if(tickets>0) { Sleep(1); cout<<"Thread1 sell tickets:"<<tickets--<<endl; } else break; LeaveCriticalSection(&g_cs); //5.執行完代碼段的就離開臨界區,那么下個線程就可以訪問資源了,這就好像我們要用公用電話(共有資源),我們必須先看看電話廳里是否有人,有人就不能此時用,沒人就可以用這個資源了 } //7.注意一定要釋放,否則線程2就沒有執行的機會 “誰擁有誰釋放” return 0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); if(tickets>0) { Sleep(1); cout<<"Thread2 sell tickets:"<<tickets--<<endl; } else break; LeaveCriticalSection(&g_cs); //8.我們可以將線程2注釋起來看看,運行發現,線程1賣出第100張后不再賣了,其余的都是線程2賣的 } return 0; //6.程序這樣執行,同步建立了。沒有出現重復和0的票號 }
