多線程編程技術(shù)詳解第一講_第1頁
多線程編程技術(shù)詳解第一講_第2頁
多線程編程技術(shù)詳解第一講_第3頁
多線程編程技術(shù)詳解第一講_第4頁
多線程編程技術(shù)詳解第一講_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、多線程編程技術(shù)詳解第一講:線程基礎(chǔ)主講人:步磊峰主講人:步磊峰 UIPower 3D界面引擎負(fù)責(zé)人界面引擎負(fù)責(zé)人 第一節(jié):進(jìn)程進(jìn)程的概念進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,在傳統(tǒng)的操作系統(tǒng)中,是資源的分配單位又是高度運(yùn)行的單位。在現(xiàn)代操作系統(tǒng)中,進(jìn)程是資源的分配單位,一個(gè)進(jìn)程通常定義為程序的一個(gè)實(shí)例。在32位Windows中,進(jìn)程占據(jù)4GB(2的32次方)的虛擬地址空間。第一節(jié):進(jìn)程進(jìn)程的組成部分進(jìn)程由兩個(gè)部分組成:操作系統(tǒng)用來管理進(jìn)程的內(nèi)核對象。內(nèi)核對象也是系統(tǒng)用來存放關(guān)于進(jìn)程的統(tǒng)計(jì)信息的地方地址空間。它包含所有可執(zhí)行模塊或DLL模塊的代碼和數(shù)據(jù)。它還包含動(dòng)態(tài)內(nèi)存分配的空間。如線程堆棧和

2、堆分配空間第一節(jié):進(jìn)程進(jìn)程是不活潑的進(jìn)程從來不執(zhí)行任何東西,它只是線程的容器。若要使進(jìn)程完成某項(xiàng)操作,它必須擁有一個(gè)在它的環(huán)境中運(yùn)行的線程,此線程負(fù)責(zé)執(zhí)行包含在進(jìn)程的地址空間中的代碼。第一節(jié):進(jìn)程進(jìn)程中的線程單個(gè)進(jìn)程可能包含若干個(gè)線程,這些線程都“同時(shí)” 執(zhí)行進(jìn)程地址空間中的代碼。每個(gè)進(jìn)程至少擁有一個(gè)線程,來執(zhí)行進(jìn)程的地址空間中的代碼。當(dāng)創(chuàng)建一個(gè)進(jìn)程時(shí),操作系統(tǒng)會自動(dòng)創(chuàng)建這個(gè)進(jìn)程的第一個(gè)線程,稱為主線程。此后,該線程可以創(chuàng)建其他的線程第二節(jié):線程線程的概念線程是指進(jìn)程中執(zhí)行運(yùn)行的最小單位,即處理機(jī)調(diào)度的基本單位。和進(jìn)程相比,進(jìn)程是一項(xiàng)任務(wù),線程是獨(dú)立子任務(wù),可由不同處理器分別來完成,提高了進(jìn)程

3、運(yùn)行速度。線程的組成部分線程由兩部分組成:a) 線程的內(nèi)核對象,操作系統(tǒng)用它來對線程實(shí)施管理。內(nèi)核對象也是系統(tǒng)用來存放線程統(tǒng)計(jì)信息的地方。b) 線程堆棧,它用于維護(hù)線程在執(zhí)行代碼時(shí)需要的所有參數(shù)和局部變量第二節(jié):線程線程的概念線程是指進(jìn)程中執(zhí)行運(yùn)行的最小單位,即處理機(jī)調(diào)度的基本單位。和進(jìn)程相比,進(jìn)程是一項(xiàng)任務(wù),線程是獨(dú)立子任務(wù),可由不同處理器分別來完成,提高了進(jìn)程運(yùn)行速度。線程的組成部分線程由兩部分組成:a) 線程的內(nèi)核對象,操作系統(tǒng)用它來對線程實(shí)施管理。內(nèi)核對象也是系統(tǒng)用來存放線程統(tǒng)計(jì)信息的地方。b) 線程堆棧,它用于維護(hù)線程在執(zhí)行代碼時(shí)需要的所有參數(shù)和局部變量第二節(jié):線程何時(shí)創(chuàng)建線程線程示

4、例比如:1)電子表格軟件可以在后臺執(zhí)行重新計(jì)算。2)Web瀏覽器可以在后臺與其服務(wù)器進(jìn)行通信。在當(dāng)前的結(jié)果顯示出來之前,用戶可以調(diào)整瀏覽器窗口的大小,或者轉(zhuǎn)到其他網(wǎng)站)。3)可以使用操作系統(tǒng)附帶的磁盤碎片整理程序,它是在系統(tǒng)空閑的時(shí)候,在后臺運(yùn)行這個(gè)實(shí)用程序并進(jìn)行磁盤碎片整理第二節(jié):線程何時(shí)不應(yīng)該創(chuàng)建線程線程示例比如:1)開發(fā)一個(gè)字處理程序,并且希望允許打印函數(shù)在它自己的線程中運(yùn)行第三節(jié):線程的創(chuàng)建 CreateThread HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize,LPTHR

5、EAD_START_ROUTINElpStartAddress, LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId); lpThreadAttributes 指向SECURITY_ATTRIBUTES型態(tài)的結(jié)構(gòu)的指針,這個(gè)參數(shù)通常設(shè)置為NULLdwStackSize 設(shè)置初始棧的大小,以字節(jié)為單位,如果為0,那么默認(rèn)將使用與調(diào)用該函數(shù)的線程相同的??臻g大小。任何情況下,Windows根據(jù)需要?jiǎng)討B(tài)延長堆棧的大小第三節(jié):線程的創(chuàng)建 CreateThread lpStartAddress, 指向線程函數(shù)的指針,函數(shù)名稱沒有限制,但

6、是必須以下列形式聲明:DWORD WINAPI ThreadProc (LPVOID lpParam) ,格式不正確將無法調(diào)用成功lpParameter, 向線程函數(shù)傳遞的參數(shù),是一個(gè)指向結(jié)構(gòu)的指針,不需傳遞參數(shù)時(shí),為NULLdwCreationFlags, 線程標(biāo)志,可取值如下(1)CREATE_SUSPENDED(0 x00000004):創(chuàng)建一個(gè)掛起的線程,(2)0:表示創(chuàng)建后立即激活。lpThreadId lpThreadId:保存新線程的id。 第三節(jié):線程的創(chuàng)建 注意事項(xiàng)如果你不需要線程ID,lpThreadId參數(shù)可以被設(shè)為NULL,但這只在WindowsNT中才行得通,Wind

7、ows95中就不行。如果你要寫一個(gè)程序可以在Windows 95中運(yùn)行,不要把lpThreadId參數(shù)設(shè)為NULL。調(diào)用CreateThread時(shí),系統(tǒng)會創(chuàng)建一個(gè)線程內(nèi)核對象,這個(gè)線程內(nèi)核對象不是線程本身,而是一個(gè)較小的數(shù)據(jù)結(jié)構(gòu),操作系統(tǒng)用這個(gè)結(jié)構(gòu)來管理線程,可以把線程內(nèi)核對象想象為一個(gè)由線程統(tǒng)計(jì)信息構(gòu)成的小型數(shù)據(jù)結(jié)構(gòu)。第四節(jié):線程的終止 線程的終止線程可以通過以下3種方法來終止運(yùn)行 線程函數(shù)返回(這是強(qiáng)烈推薦的)。線程通過調(diào)用ExitThread函數(shù)“殺死”自己(要避免使用這種方法)1.同一個(gè)進(jìn)程或另一個(gè)進(jìn)程中的線程調(diào)用TerminateThread函數(shù)(要避免使用這種方法)第四節(jié):線程的終

8、止第一種:線程函數(shù)返回 設(shè)計(jì)線程函數(shù)時(shí),應(yīng)該讓線程自己返回,這樣可以確保以下正確的應(yīng)用程序清理工作都得以執(zhí)行。 線程函數(shù)中創(chuàng)建的所有C+對象都通過其析構(gòu)函數(shù)被正確銷毀。操作系統(tǒng)正確釋放線程棧使用的內(nèi)存。操作系統(tǒng)把線程的退出代碼(在線程的內(nèi)核對象中維護(hù))設(shè)為線程函數(shù)的返回值1.系統(tǒng)遞減少線程的內(nèi)核對象的使用計(jì)數(shù)。第四節(jié):線程的終止第二種:ExitThread函數(shù) 該函數(shù)將終止線程的運(yùn)行,并導(dǎo)致操作系統(tǒng)清理該線程使用的所有操作系統(tǒng)資源。但是,你的C/C+資源(如C+類對象)不會被銷毀。有鑒于些,更好的做法是直接從線程函數(shù)返回,不要自己調(diào)用ExitThread函數(shù)第三種:TerminateThrea

9、d函數(shù) 不同于ExitThread總是”殺死“主調(diào)線程,TerminateThread能”殺死“任何線程。TerminateThread函數(shù)是異步的,所以函數(shù)返回時(shí),并不保證線程已經(jīng)終止了。第五節(jié):線程的掛起和恢復(fù)ResumeThread函數(shù)DWORD ResumeThread(HANDLE hThread); hThread 指定的要重新運(yùn)行的線程的句柄如果ResumeThread函數(shù)成功,它將返回線程的前一個(gè)掛起計(jì)數(shù),否則,它將返回0 xFFFFFFFF.一個(gè)線程可以被多次掛起。如果一個(gè)線程被掛起三次,那么必需調(diào)用ResumeThread三次,才能使起線程運(yùn)行。第五節(jié):線程的掛起和恢復(fù)Su

10、spendThread函數(shù)DWORD SuspendThread(HANDLE hThread); hThread 指定的要掛起的線程的句柄如果SuspendThread函數(shù)成功,它將返回線程的前一個(gè)掛起計(jì)數(shù),否則,它將返回0 xFFFFFFFF.在實(shí)際開發(fā)中,應(yīng)用程序在調(diào)用SuspendThread時(shí)必需小心,因?yàn)樵噲D掛起一個(gè)線程時(shí),我們不知道線程在做什么,比如說如果線程正在分配堆中的內(nèi)存,線程將鎖定堆,當(dāng)其他線程要訪問堆的時(shí)候,它們的執(zhí)行將被中止,直到第一個(gè)線程恢復(fù)。第六節(jié):線程睡眠Sleep函數(shù)使得線程在一段時(shí)間內(nèi)自己不需要調(diào)度 void Sleep(DWORD dwMillisecon

11、ds); dwMilliseconds毫秒時(shí)間第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序向?qū)蒚hreadDemo控制臺程序打開vs2008編輯器選擇“文件”-“新建”-“項(xiàng)目”-彈出“新建項(xiàng)目對

12、話框”在“項(xiàng)目類型”下選擇“Win32”在右邊“模板下”選擇“Win32項(xiàng)目”在下面輸入項(xiàng)目的名稱:ThreadDemo選擇項(xiàng)目存放的位置然后點(diǎn)擊“確定“然后直接點(diǎn)擊”完成“,如圖第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫

13、ThreadDemo程序最終的程序效果第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序修改背景顏色在MyRegisterClass函數(shù)里,修改代碼如下:wcex.hbrBackground= (HBRUS

14、H)(CTLCOLOR_BTN+1);第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序禁用最大化按鈕在InitInstance函數(shù)里修改CreateWindow函數(shù) hWnd = CreateWindow

15、(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW &WS_MAXIMIZEBOX, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);另一種方式:LONG lStyle = GetWindowLong(hWnd,GWL_STYLE);lStyle &= WS_MAXIMIZEBOX;SetWindowLong(hWnd,GWL_STYLE,lStyle);第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背

16、景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序創(chuàng)建三個(gè)線程在WM_CREATE消息里添加三個(gè)線程ThrHandle1 = CreateThread(NULL,0,ThreadProc1,NULL,CREATE_SUSPENDED,NULL);ThrHandle2 = CreateThread(NULL,0,

17、ThreadProc2,NULL,CREATE_SUSPENDED,NULL);ThrHandle3 = CreateThread(NULL,0,ThreadProc3,NULL,CREATE_SUSPENDED,NULL);定義三個(gè)全局的線程句柄,并初始化為NULLHANDLE ThrHandle1 = NULL; /線程的線程句柄HANDLE ThrHandle2 = NULL;/線程的線程句柄HANDLE ThrHandle3 = NULL;/線程的線程句柄第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5

18、、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序?qū)崿F(xiàn)CreateEditControlForMainWnd函數(shù)創(chuàng)建編輯器控件 HWND CreateEditControlForMainWnd( int x, / horizontal position of window int y, / vertical position of wi

19、ndow int nWidth, / window width int nHeight, / window height HWND hWndParent, / handle to parent or owner window HINSTANCE hInstance / handle to application instance)return CreateWindow(_T(EDIT),_T(0),WS_CHILD | WS_VISIBLE,x,y,nWidth,nHeight,hWndParent,NULL,hInstance,NULL);第七節(jié):編寫ThreadDemo程序?qū)崿F(xiàn)Create

20、StaticForMainWnd函數(shù)創(chuàng)建靜態(tài)控件void CreateStaticForMainWnd( LPCTSTR lpWindowName, / window nameint x, / horizontal position of windowint y, / vertical position of windowint nWidth, / window widthint nHeight, / window heightHWND hWndParent, / handle to parent or owner windowHINSTANCE hInstance / handle to a

21、pplication instance)CreateWindow(_T(STATIC),lpWindowName,WS_CHILD | WS_VISIBLE,x,y,nWidth,nHeight,hWndParent,NULL,hInstance,NULL);第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、

22、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序在WM_CREATE消息里添加相關(guān)代碼創(chuàng)建三個(gè)靜態(tài)窗口、三個(gè)編輯器窗口第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫Thr

23、eadDemo程序添加菜單在“資源視圖”里添加“啟動(dòng)”和“暫?!安藛?,設(shè)置”啟動(dòng)“的ID號為IDM_RESUME,設(shè)置”暫?!暗腎D號為IDM_SUSPEN,并且在”Enabled“設(shè)為False,這樣在線程還沒有啟動(dòng)時(shí),暫停菜單是不可用的 如圖:在WM_CREATE消息里獲得菜單的句柄hMenu = GetMenu(hWnd);在WndProc函數(shù)內(nèi)的開頭部分定義hMenu窗口的句柄,這里的句柄設(shè)為靜態(tài)的第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlF

24、orMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序處理菜單消息EnableMenuItem函數(shù)用于設(shè)置菜單是可用的、或不可用的。DrawMenuBar 函數(shù)用于菜單欄發(fā)生改變的時(shí)候,重繪它ResumeThread 函數(shù)用于重新啟動(dòng)線程SuspendThread 函數(shù)用于重新暫停線程如圖:第七節(jié):編寫ThreadDemo程序1、向?qū)蒚hreadDemo控制臺程序2、最終的程序效果3、修改背景

25、顏色4、禁用最大化窗口5、創(chuàng)建三個(gè)線程6、實(shí)現(xiàn)CreateEditControlForMainWnd函數(shù)和CreateStaticForMainWnd函數(shù) 7、在WM_CREATE消息里添加相關(guān)代碼8、添加菜單9、處理菜單消息10、編寫線程函數(shù)11、處理WM_PAINT消息和WM_DESTROY消息第七節(jié):編寫ThreadDemo程序編寫線程函數(shù)線程函數(shù)形式DWORD WINAPI ThreadProc(LPVOIDlpParameter);當(dāng)然,ThreadProc這個(gè)函數(shù)名是任意指定的,但是你不能去掉WINAPI這個(gè)符號,如果那樣,那么在你啟動(dòng)線程后,線程就會墜毀。那WINAPI是什么呢,

26、其實(shí)WINAPI只是一種調(diào)用約定而已第七節(jié):編寫ThreadDemo程序編寫線程函數(shù)ThreadProc1線程函數(shù)1)首先獲得DC2)創(chuàng)建一個(gè)紅色的畫刷并選到DC里面去3)循環(huán)打印數(shù)字,當(dāng)數(shù)字能被整除時(shí),就畫一個(gè)硬幣4)在每次循環(huán)后都會調(diào)用Sleep睡眠毫秒,這是為了讓當(dāng)前線程暫時(shí)放棄剩余的時(shí)間片,好讓其它線程可以執(zhí)行5)把舊的畫刷選回去,并刪除新的畫刷6)最后釋放DC代碼如下:第七節(jié):編寫ThreadDemo程序編寫線程函數(shù)ThreadProc1線程函數(shù)DWORD WINAPI ThreadProc1(LPVOID lpParameter)TCHAR szBuf10=0;int index

27、=0;/獲得DCHDC hdc = GetDC(hMainWnd);/創(chuàng)建一個(gè)紅色的畫刷并選到DC里面去HBRUSH hBr = CreateSolidBrush(RGB(255,0,0);HBRUSH hOldBr = static_cast(SelectObject(hdc,hBr);第七節(jié):編寫ThreadDemo程序編寫線程函數(shù)ThreadProc1線程函數(shù)/循環(huán)打印到的數(shù)字,并且當(dāng)數(shù)字能被整除時(shí),就畫一個(gè)硬幣for(int i=0; i1000; +i)wsprintf(szBuf,_T(%d),i+1);SetWindowText(ThrhWnd1,szBuf);if(0 = i%100)int y = 250 -10*index;Ellipse(hdc,100,y,200,y-30);Ellipse(hdc,100,y-10,200,y-36);index+;thrCoins1=index;Sleep(100);第七節(jié):編寫ThreadDemo程序編寫線程函數(shù)ThreadProc1線程函數(shù)/把舊的畫刷選回去,并刪除新的畫刷SelectObject(hdc,hOldBr);DeleteObject(hBr);/釋放DCReleaseDC(hMainWnd

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論