windows多線程編程_第1頁
windows多線程編程_第2頁
windows多線程編程_第3頁
windows多線程編程_第4頁
windows多線程編程_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、一:利用事件實現(xiàn)線程同步1. createthread函數(shù)的用法hThread = CreateThread(&security_attributes, dwStackSize, ThreadProc,pParam, dwFlags, &idThread) ; HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD

2、 lpThreadId); 第一個參數(shù)是指向SECURITY_ATTRIBUTES型態(tài)的結(jié)構(gòu)的指針。在Windows 98中忽略該參數(shù)。在Windows NT中,它被設(shè)為NULL。第二個參數(shù)是用于新線程的初始堆棧大小,默認值為0。在任何情況下,Windows根據(jù)需要動態(tài)延長堆棧的大小。第三個參數(shù)是指向線程函數(shù)的指標(biāo)。函數(shù)名稱沒有限制,但是必須以下列形式聲明:DWORD WINAPI ThreadProc (LPVOID pParam) ;第四個參數(shù)為傳遞給ThreadProc的參數(shù)。這樣主線程和從屬線程就可以共享數(shù)據(jù),這個參數(shù)既可以是數(shù)值,也可以是指向其他信息的指針。第五個參數(shù)通常為0,表示創(chuàng)

3、建之后立刻運行,但當(dāng)建立的線程不馬上執(zhí)行時為可設(shè)置為CREATE_SUSPENDED。線程將暫停直到呼叫ResumeThread來恢復(fù)線程的執(zhí)行為止。第六個參數(shù)時一個返回值,它用來接收線程的ID,可以為該參數(shù)傳遞NULL,表明我們對該線程的ID不感興趣。函數(shù)返回值為新線程的句柄。2. CreateEvent函數(shù)HANDLECreateEvent(LPSECURITY_ATTRIBUTESlpEventAttributes,/ 安全屬性BOOLbManualReset,/ 復(fù)位方式BOOLbInitialState,/ 初始狀態(tài)LPCTSTRlpName / 對象名稱);lpEventAttri

4、butes輸入一個指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針,確定返回的句柄是否可被子進程繼承。如果lpEventAttributes是NULL,此句柄不能被繼承。Windows NT/2000:lpEventAttributes的結(jié)構(gòu)中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個默認的安全符。bManualReset輸入指定將事件對象創(chuàng)建成手動復(fù)原還是自動復(fù)原。如果是TRUE,那么必須用ResetEvent函數(shù)來手工將事件的狀態(tài)復(fù)原到無信號狀態(tài)。如果設(shè)置為FALSE,當(dāng)一個等待線程被釋放以后,系統(tǒng)將會自動將事件狀態(tài)復(fù)原為無信號狀

5、態(tài)。bInitialState輸入指定事件對象的初始狀態(tài)。如果為TRUE,初始狀態(tài)為有信號狀態(tài);否則為無信號狀態(tài)。lpName輸入指定事件的對象的名稱,是一個以0結(jié)束的字符串指針。名稱的字符格式限定在MAX_PATH之內(nèi)。名字是對大小寫敏感的。如果lpName指定的名字,與一個存在的命名的事件對象的名稱相同,函數(shù)將請求EVENT_ALL_ACCESS來訪問存在的對象。這時候,由于bManualReset和bInitialState參數(shù)已經(jīng)在創(chuàng)建事件的進程中設(shè)置,這兩個參數(shù)將被忽略。如果lpEventAttributes是參數(shù)不是NULL,它將確定此句柄是否可以被繼承,但是其安全描述符成員將被忽

6、略。如果lpName為NULL,將創(chuàng)建一個無名的事件對象。如果lpName的和一個存在的信號、互斥、等待計時器、作業(yè)或者是文件映射對象名稱相同,函數(shù)將會失敗,在GetLastError函數(shù)中將返回ERROR_INVALID_HANDLE。造成這種現(xiàn)象的原因是這些對象共享同一個命名空間。終端服務(wù)(Terminal Services):名稱中可以加入Global或是Local的前綴,這樣可以明確的將對象創(chuàng)建在全局的或事務(wù)的命名空間。名稱的其它部分除了反斜杠(),可以使用任意字符。詳細內(nèi)容可參考Kernel Object Name Spaces。Windows 2000:在Windows 2000系

7、統(tǒng)中,沒有終端服務(wù)運行,Global和Local前綴將被忽略。名稱的其它部分除了反斜杠(),可以使用任意字符。Windows NT 4.0以及早期版本,Windows 95/98:名稱中除了反斜杠(),可以使用任意字符。/ MultiThread.cpp : 定義控制臺應(yīng)用程序的入口點。代碼一:線程不同步的例子(基于事件)#include stdafx.h#include stdio.h#include windows.hDWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter);HAN

8、DLE g_hEvent;int tiket=100;int _tmain(int argc, _TCHAR* argv)HANDLE Thread1;HANDLE Thread2;g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);SetEvent(g_hEvent);/Sle

9、ep(10);system(pause);return 0;DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(1)/Sleep(1);if(tiket0)WaitForSingleObject(g_hEvent,INFINITE);printf(Thread1 sell tiket %dn,tiket);tiket-;SetEvent(g_hEvent);else/SetEvent(g_hEvent);break;return 0;DWORD WINAPI Fun2Proc(LPVOID lpParameter)while(1)/Sleep(1);W

10、aitForSingleObject(g_hEvent,INFINITE);if(tiket0)printf(Thread2 sell tiket %dn,tiket);tiket-;SetEvent(g_hEvent);else/SetEvent(g_hEvent);break;return 0;代碼二:線程同步的例子(基于事件)#include stdafx.h#include stdio.h#include windows.hDWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter

11、);HANDLE g_hEvent;int tiket=100;int _tmain(int argc, _TCHAR* argv)HANDLE Thread1;HANDLE Thread2;g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);SetEvent(g_hEvent)

12、;/Sleep(10);system(pause);return 0;DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(1)/Sleep(1);WaitForSingleObject(g_hEvent,INFINITE);if(tiket0)printf(Thread1 sell tiket %dn,tiket);tiket-;SetEvent(g_hEvent);else/SetEvent(g_hEvent);break;return 0;DWORD WINAPI Fun2Proc(LPVOID lpParameter)while(1)/Sleep

13、(1);WaitForSingleObject(g_hEvent,INFINITE);if(tiket0)printf(Thread2 sell tiket %dn,tiket);tiket-;SetEvent(g_hEvent);else/SetEvent(g_hEvent);break;return 0;二:利用互斥對象實現(xiàn)線程同步CreateMutex()函數(shù)可用來創(chuàng)建一個有名或無名的互斥量對象,該對象是一個內(nèi)核對象,它能夠確保線程對單個資源的互斥訪問權(quán)。其函數(shù)原型為:HANDLE CreateMutex(LPSECURITY_ATTRIBUTESlpMutexAttributes, /

14、 指向安全屬性的指針BOOLbInitialOwner, / 初始化互斥對象的所有者LPCTSTRlpName/ 指向互斥對象名的指針);返回值:如執(zhí)行成功,就返回互斥體對象的句柄;零表示出錯。會設(shè)置GetLastError。即使返回的是一個有效句柄,但倘若指定的名字已經(jīng)存在,GetLastError也會設(shè)為ERROR_ALREADY_EXISTS。參數(shù)表:lpMutexAttributes SECURITY_ATTRIBUTES,指定一個SECURITY_ATTRIBUTES結(jié)構(gòu),可以賦值NULL,表示讓互斥對象擁有默認的安全屬性。bInitialOwner Long:若為TRUE,則創(chuàng)建該

15、互斥對象的線程擁有該互斥對象的所有權(quán),否則,沒有所有權(quán)。lpName String,指定互斥體對象的名字。若為NULL,表示創(chuàng)建一個匿名的互斥對象。注意:如果線程對共享資源的訪問結(jié)束后,應(yīng)該釋放互斥對象的所有權(quán),即將互斥對象置于有信號的狀態(tài),使用函數(shù)BOOL WIANPI ReleaseMutex(HANDLE hMutex);返回值:函數(shù)返回成功,返回非0,否則返回0;參數(shù):互斥對象的句柄。對于互斥對象遵循誰擁有誰釋放的原則。代碼三:#include stdafx.h#include stdio.h#include windows.hDWORD WINAPI Fun1Proc(LPVOID

16、lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter);HANDLE h_Mutex;int tiket=100;int _tmain(int argc, _TCHAR* argv)HANDLE Thread1;HANDLE Thread2;h_Mutex=CreateMutex(NULL,FALSE,NULL);Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thr

17、ead1);CloseHandle(Thread2);/Sleep(10);system(pause);return 0;DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(1)/Sleep(1);WaitForSingleObject(h_Mutex,INFINITE);if(tiket0)printf(Thread1 sell tiket %dn,tiket);tiket-;ReleaseMutex(h_Mutex);elsebreak;return 0;DWORD WINAPI Fun2Proc(LPVOID lpParameter)while(

18、1)/Sleep(1);WaitForSingleObject(h_Mutex,INFINITE);if(tiket0)printf(Thread2 sell tiket %dn,tiket);tiket-;ReleaseMutex(h_Mutex);elsebreak;return 0;三:利用關(guān)鍵代碼段(臨界區(qū))實現(xiàn)線程同步關(guān)鍵代碼段,也稱為臨界區(qū),工作在用戶方式下,它是指一小段代碼,在代碼能夠執(zhí)行前,它必須獨占對某些資源的訪問權(quán)。VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection )函數(shù)功能初始化一個臨界

19、資源對象。該函數(shù)無返回值。單進程的各個線程可以使用臨界資源對象來解決同步互斥問題,該對象不能保證哪個線程能夠獲得到臨界資源對象,該系統(tǒng)能公平的對待每一個線程。lpCriticalSection臨界資源對象指針,該參數(shù)是一個out類型。 EnterCriticalSection(_inoutLPCRITICAL_SECTIONlpCriticalSection);該函數(shù)用以獲得指定的臨界區(qū)的對象的所有權(quán),該函數(shù)等待臨界區(qū)對象的所有權(quán),如果該所有權(quán)賦予了調(diào)用線程,則該函數(shù)返回,否則該函數(shù)會一直等待,從而導(dǎo)致線程等待。LeaveCriticalSection(_inoutLPCRITICAL_SEC

20、TIONlpCriticalSection);線程使用完所保護的資源后,需要調(diào)用該函數(shù),釋放指定的臨界區(qū)對象的所有權(quán),這時候其他想要獲得該臨界區(qū)對象所有權(quán)的線程就可以獲得該所有權(quán),從而進入關(guān)鍵代碼段,訪問保護的資源。DeleteCriticalSection(_inoutLPCRITICAL_SECTIONlpCriticalSection);該函數(shù)釋放一個沒有被任何線程所擁有的臨界區(qū)對象的所有資源。代碼四:#include stdafx.h#include stdio.h#include windows.hDWORD WINAPI Fun1Proc(LPVOID lpParameter);D

21、WORD WINAPI Fun2Proc(LPVOID lpParameter);CRITICAL_SECTION g_cs;int tiket=100;int _tmain(int argc, _TCHAR* argv)HANDLE Thread1;HANDLE Thread2;Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(Thread1);CloseHandle(Thread2);InitializeCritica

22、lSection(&g_cs);/Sleep(10);system(pause);DeleteCriticalSection(&g_cs);return 0;DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(1)/Sleep(1);EnterCriticalSection(&g_cs);if(tiket0)printf(Thread1 sell tiket %dn,tiket);tiket-;LeaveCriticalSection(&g_cs);elsebreak;return 0;DWORD WINAPI Fun2Proc(LPVOID lpPa

23、rameter)while(1)/Sleep(1);EnterCriticalSection(&g_cs);if(tiket0)printf(Thread2 sell tiket %dn,tiket);tiket-;LeaveCriticalSection(&g_cs);elsebreak;return 0;四:線程死鎖解釋:對于多線程來說,如果線程1擁有了臨界區(qū)對象A,等待臨界區(qū)對象B的擁有權(quán),線程2擁有了臨界區(qū)對象B,等待臨界區(qū)對象A的所有權(quán),這就造成了死鎖。代碼五:線程死鎖#include stdafx.h#include stdio.h#include windows.hDWORD WINAPI Fun1Proc(LPVOID lpParameter);DWORD WINAPI Fun2Proc(LPVOID lpParameter);CRITICAL_SECTION g_cs;CRITICAL_SECTION g_cs1;int tiket=100;int _tmain(int argc, _TCHAR* argv)HANDLE Thread1;HANDLE Thread2;Thread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);Thread2=CreateTh

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論