網(wǎng)絡(luò)編程實(shí)用教程第7-8章-多線程編程_第1頁(yè)
網(wǎng)絡(luò)編程實(shí)用教程第7-8章-多線程編程_第2頁(yè)
網(wǎng)絡(luò)編程實(shí)用教程第7-8章-多線程編程_第3頁(yè)
網(wǎng)絡(luò)編程實(shí)用教程第7-8章-多線程編程_第4頁(yè)
網(wǎng)絡(luò)編程實(shí)用教程第7-8章-多線程編程_第5頁(yè)
已閱讀5頁(yè),還剩57頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

網(wǎng)絡(luò)編程實(shí)用教程,第7章WinSock的多線程編程,本章內(nèi)容:WinSock需要多線程編程的原因:Win32操作系統(tǒng)下的多進(jìn)程多線程機(jī)制、多線程機(jī)制在網(wǎng)絡(luò)編程中的應(yīng)用和VisualC+6.0對(duì)多線程網(wǎng)絡(luò)編程的支持。分析了MFC支持的兩種線程,給出了創(chuàng)建MFC的工作線程、創(chuàng)建并啟動(dòng)用戶界面線程和終止線程的步驟。,7.1WinSock為什么需要多線程編程,7.1.1WinSock的兩種輸入輸出模式,如前所述,WinSock在進(jìn)行輸入輸出的時(shí)候,可以使用兩種工作模式:“阻塞”模式:又稱為同步模式“非阻塞”模式:又稱為異步模式工作在“阻塞”模式下的套接字被稱為阻塞套接字,而工作在“非阻塞”模式下的套接字稱為非阻塞套接字。,7.1.2兩種模式的優(yōu)缺點(diǎn)及解決方法,“阻塞”與“非阻塞”模式的優(yōu)點(diǎn)和缺點(diǎn):阻塞套接字的I/O操作工作情況比較確定,即調(diào)用、等待、返回。大部分情況下,I/O操作都能成功地完成,只是花費(fèi)了等待的時(shí)間,容易編程;需要建立多個(gè)套接字連接來(lái)為多個(gè)客戶服務(wù)的時(shí)候,或在數(shù)據(jù)的收發(fā)量不均勻的時(shí)候,或在輸入輸出的時(shí)間不確定的時(shí)候,阻塞套接字的性能低下,甚至無(wú)能為力。,使用非阻塞套接字,需要編寫(xiě)更多的代碼,因?yàn)楸仨毲‘?dāng)?shù)匕盐照{(diào)用I/O函數(shù)的時(shí)機(jī),盡量減少無(wú)功而返的調(diào)用,還必須詳加分析每個(gè)Winsock調(diào)用中收到的錯(cuò)誤,采取相應(yīng)的對(duì)策,這種I/O操作的隨機(jī)性使得非阻塞套接字顯得難于操作。所以必須采取適當(dāng)?shù)膶?duì)策,讓阻塞和非阻塞套接字能夠滿足各種場(chǎng)合的要求。對(duì)于非阻塞工作模式:引入了五種“套接字I/O模型”。阻塞的工作模式,則引入了多線程機(jī)制。,7.2Win32操作系統(tǒng)下的多進(jìn)程多線程機(jī)制,7.2.2Win32OS支持多線程,應(yīng)用程序、進(jìn)程及線程的關(guān)系DOS是單用戶單任務(wù)的。Win32操作系統(tǒng)是多任務(wù)的,并且支持一個(gè)進(jìn)程中有多個(gè)線程。一個(gè)線程(thread)是進(jìn)程內(nèi)的一條執(zhí)行路徑,是一個(gè)應(yīng)用程序中的一條可執(zhí)行路徑。一個(gè)進(jìn)程中至少要有一個(gè)線程,稱為主線程。當(dāng)啟動(dòng)了一個(gè)應(yīng)用程序時(shí),操作系統(tǒng)將為它創(chuàng)建了一個(gè)進(jìn)程,同時(shí)創(chuàng)建該進(jìn)程的主線程,并開(kāi)始執(zhí)行主線程。主線程可以創(chuàng)建并啟動(dòng)其他輔助線程,由主線程創(chuàng)建的線程又可以創(chuàng)建并啟動(dòng)更多的線程。,7.2.2Win32OS支持多線程,單CPU分時(shí)地運(yùn)行進(jìn)程中的各個(gè)線程,7.2.3多線程機(jī)制在網(wǎng)絡(luò)編程中的應(yīng)用,如果一個(gè)應(yīng)用程序,有多個(gè)任務(wù)需要同時(shí)進(jìn)行處理,則適合使用多線程機(jī)制。對(duì)于網(wǎng)絡(luò)上客戶機(jī)軟件:采用多線程,能克服在單線程的編程模式下,由于阻塞等待而產(chǎn)生的客戶程序就不能及時(shí)響應(yīng)用戶的操作命令的問(wèn)題。對(duì)于網(wǎng)絡(luò)上服務(wù)器軟件:采用多線程的編程技術(shù),能更好地為多個(gè)客戶服務(wù)。對(duì)于一個(gè)客戶:采用多線程機(jī)制也能大大提高應(yīng)用程序的運(yùn)行效率。網(wǎng)絡(luò)在線實(shí)時(shí)監(jiān)控軟件:,7.3VC6.0對(duì)多線程網(wǎng)絡(luò)編程的支持,VC6.0環(huán)境下,兩種開(kāi)發(fā)程序的方法:直接使用Win32API來(lái)編寫(xiě)Win32應(yīng)用程序利用MFC基礎(chǔ)類庫(kù)編寫(xiě)C+風(fēng)格的應(yīng)用程序。在這兩種Windows應(yīng)用程序的開(kāi)發(fā)方式下,多線程的編程原理是一致的。,7.3.1MFC支持的兩種線程,微軟的基礎(chǔ)類庫(kù)MFC提供了對(duì)于多線程應(yīng)用程序的支持。在MFC中,線程分為兩種:用戶接口線程:(user-interfacethread),或稱用戶界面線程;工作線程:(theworkerthread),這兩類線程可以滿足不同任務(wù)的處理需求。,1、用戶接口線程作用:用于處理用戶的輸入,響應(yīng)用戶產(chǎn)生的消息。MFC為用戶接口線程提供了一個(gè)消息泵。同時(shí)包含一個(gè)消息循環(huán),以應(yīng)對(duì)各種事件。MFC應(yīng)用程序的CWinApp類對(duì)象是一個(gè)典型的用戶接口線程在MFC應(yīng)用程序中,CWinThread是用戶接口線程的基類,CWinApp就是從CWinThread類派生出來(lái)的,編寫(xiě)用戶接口線程候,也需要從CWinThread類派生。,2工作線程工作線程(workerthread),適用于處理那些不要求用戶輸入并且比較消耗時(shí)間的其他任務(wù)。對(duì)用戶來(lái)說(shuō),工作線程運(yùn)行在后臺(tái)。這就使得工作線程特別適合去等待一個(gè)事件的發(fā)生。CWinThread類同樣是工作線程的基類。在編寫(xiě)工作線程的時(shí)候,可以調(diào)用MFC的AfxBeginThread函數(shù),來(lái)創(chuàng)建CWinThread對(duì)象。,7.3.2創(chuàng)建MFC的工作線程,利用MFC創(chuàng)建工作線程的步驟:第一步:編程實(shí)現(xiàn)控制函數(shù)第二步:創(chuàng)建并啟動(dòng)工作線程一般不必從CWinThread派生一個(gè)類。如果需要一個(gè)特定版本的CWinThread類,也可以去派生;但對(duì)于大多數(shù)的工作線程是不要求的。可以不作任何修改地使用CWinThread類。,7.3.2創(chuàng)建MFC的工作線程,1、編程實(shí)現(xiàn)控制函數(shù)一個(gè)工作線程對(duì)應(yīng)一個(gè)控制函數(shù)。線程執(zhí)行的任務(wù)都應(yīng)編寫(xiě)在控制函數(shù)之中,規(guī)定了該線程的執(zhí)行代碼,當(dāng)控制函數(shù)執(zhí)行結(jié)束而退出時(shí),線程也就隨之終止。編寫(xiě)工作線程的控制函數(shù)必須遵守一定的格式,控制函數(shù)的原型聲明是:UINTControlFunctionName(LPVOIDpParam);pParam是一個(gè)數(shù)據(jù)結(jié)構(gòu);,7.3.2創(chuàng)建MFC的工作線程,2創(chuàng)建并啟動(dòng)工作線程(Startingthethread)啟動(dòng)線程:即開(kāi)始運(yùn)行它對(duì)應(yīng)的控制函數(shù)。在主線程或其他線程中調(diào)用AfxBeginThread()函數(shù)就可以創(chuàng)建新的線程,并使新線程開(kāi)始運(yùn)行。一般將線程的創(chuàng)建者稱為新線程的父線程。AfxBeginThread()函數(shù)有兩個(gè)重載的版本,區(qū)別在于使用的入口參數(shù)不同。,7.3.2創(chuàng)建MFC的工作線程,CWinThread*AfxBeginThread(AFX_THREADPROCpfnThreadProc,/控制函數(shù)的地址LPVOIDpParam,/數(shù)據(jù)結(jié)構(gòu)的指針,傳數(shù)據(jù)給線程控制函數(shù)intpPriority=THREAD_PRIORITY_NORMAL,/優(yōu)先級(jí)UINTnStackSize=0,/線程的堆棧大?。ň彌_區(qū))DWORDdwCreateFlags=0,/線程的運(yùn)行狀態(tài),是否被掛起LPSECURITY_ATTTRIBUTESlpSecurityAttrs=NULL/安全屬性);后面4個(gè)參數(shù)為可選參數(shù)。,創(chuàng)建工作線程的例子,3、創(chuàng)建工作線程的例子功能:求長(zhǎng)度為N的數(shù)組Arry的各元素的和。編程實(shí)現(xiàn)線程控制函數(shù)(1)/首先定義了一個(gè)結(jié)構(gòu):structintN;/數(shù)組元素的個(gè)數(shù)。double*Arry;/指向一個(gè)雙精度實(shí)數(shù)的數(shù)組myData;/定義了此結(jié)構(gòu)類型的變量,省略了初始化的代碼myDatass;,創(chuàng)建工作線程的例子,(2)/接著定義線程的控制函數(shù)。UINTMyCalcFunc(LPVOIDpParam)/如果入口參數(shù)為空指針,終止線程。if(pPara=NULL)AfxEndThread(MY_NULL_POINTER_ERROR);intN=pPara-N;/數(shù)組的元素個(gè)數(shù)。double*Arry=pPara-Arry;/指向數(shù)組的第一個(gè)元素。doublesum=0;/數(shù)組元素之和。for(inti=0;i0)if(FD_ISSET(s,2窗口回調(diào)例程應(yīng)用程序在一個(gè)套接字上調(diào)用WSAAsyncSelect函數(shù)時(shí),該函數(shù)的hWnd參數(shù)指定了一個(gè)窗口句柄。函數(shù)成功調(diào)用后,當(dāng)指定的網(wǎng)絡(luò)事件發(fā)生時(shí),會(huì)自動(dòng)執(zhí)行該窗口對(duì)應(yīng)的窗口回調(diào)例程。并將網(wǎng)絡(luò)事件通知和Windows消息的相關(guān)信息,傳遞給該例程的入口參數(shù),用戶可以在該例程中添加自己的代碼,針對(duì)不同的網(wǎng)絡(luò)事件進(jìn)行處理,從而實(shí)現(xiàn)有序的套接字輸入和輸出。,窗口回調(diào)例程應(yīng)定義成如下形式:LRESULTCALLBACKWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);,3舉例,8.3WSAEventSelect事件選擇模型,WSAEventSelect事件選擇模型和WSAAsyncSelect模型類似,它也允許程序在一個(gè)或多個(gè)套接字上,接收以事件為基礎(chǔ)的網(wǎng)絡(luò)事件通知。表8.2總結(jié)的由WSAAsyncSelect模型采用的網(wǎng)絡(luò)事件,均可原封不動(dòng)地移植到事件選擇模型中。也就是說(shuō),在用新模型開(kāi)發(fā)的應(yīng)用程序中,也能接收和處理所有那些事件。該模型最主要的差別在于,網(wǎng)絡(luò)事件會(huì)投遞至一個(gè)事件對(duì)象句柄,而非投遞至一個(gè)窗口例程。以下按照使用此模型的編程步驟介紹。,1創(chuàng)建事件對(duì)象句柄事件選擇模型要求應(yīng)用程序針對(duì)每一個(gè)套接字,首先創(chuàng)建一個(gè)事件對(duì)象。方法是調(diào)用WSACreateEvent函數(shù),它的定義如下:WSAEVENTWSACreateEvent(void);返回值:一個(gè)創(chuàng)建好的事件對(duì)象句柄。,2關(guān)聯(lián)套接字和事件對(duì)象,注冊(cè)關(guān)心的網(wǎng)絡(luò)事件有了事件對(duì)象句柄后,接下來(lái)將其與某個(gè)套接字關(guān)聯(lián)在一起,同時(shí)注冊(cè)感興趣的網(wǎng)絡(luò)事件類型(表8-2),這就需要調(diào)用WSAEventSelect函數(shù):intWSAEventSelect(SOCKETs,WSAEVENThEventObject,longlNetworkEvents);,3.等待網(wǎng)絡(luò)事件觸發(fā)事件對(duì)象句柄的工作狀態(tài)套接字同一個(gè)事件對(duì)象句柄關(guān)聯(lián)在一起以后,程序便調(diào)用WSAWaitForMultipleEvents函數(shù),等待網(wǎng)絡(luò)事件觸發(fā)事件對(duì)象句柄的工作狀態(tài):DWORDWSAWaitForMultipleEvents(DWORDcEvents,constWSAEVENTFAR*lphEvents,BOOLfWaitAll,DWORDdwTimeout,BOOLfAlertable);該函數(shù)用來(lái)等待一個(gè)或多個(gè)事件對(duì)象句柄,當(dāng)其中一個(gè)或所有句柄進(jìn)入“已傳信”狀態(tài)后,或在超過(guò)了一個(gè)規(guī)定的時(shí)間期限后,立即返回。,4檢查套接字上所發(fā)生的網(wǎng)絡(luò)事件類型知道了造成網(wǎng)絡(luò)事件的套接字后,接下來(lái)可調(diào)用WSAEnumNetworkEvents函數(shù),檢查套接字上發(fā)生了什么類型的網(wǎng)絡(luò)事件。該函數(shù)定義如下:intWSAEnumNetworkEvents(SOCKETs,WSAEVENThEventObject,LPWSANETWORKEVENTSlpNetworkEvents);,5處理網(wǎng)絡(luò)事件在確定了套接字上發(fā)生的網(wǎng)絡(luò)事件類型后,可以根據(jù)不同的情況做出相應(yīng)的處理。完成了對(duì)WSANETWORKEVENTS結(jié)構(gòu)中的事件的處理之后,應(yīng)用程序應(yīng)在所有可用的套接字上,繼續(xù)等待更多的網(wǎng)絡(luò)事件。完成了對(duì)一個(gè)事件對(duì)象的處理后,應(yīng)調(diào)用WSACloseEvent函數(shù),釋放由事件句柄使用的系統(tǒng)資源。函數(shù)的定義如下:BOOLWSACloseEvent(WSAEVENThEvent);該函數(shù)也將一個(gè)事件句柄作為自己唯一的參數(shù),并會(huì)在成功后返回TRUE,失敗后返回FALSE。,6舉例,8.4其他模型,重疊I/O模型在Winsock中,能使應(yīng)用程序達(dá)到更佳的性能。重疊模型的基本原理是讓?xiě)?yīng)用程序使用一個(gè)重疊的數(shù)據(jù)結(jié)構(gòu),一次投遞一個(gè)或多個(gè)Winsock的I/O請(qǐng)求。針對(duì)那些提交的請(qǐng)求,在它們完成之后,應(yīng)用程序可為它們提供服務(wù)。自Winsock2.0發(fā)布開(kāi)始,重疊I/O便已集成到新的Winsock函數(shù)中。

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論