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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

溫馨提示

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

評論

0/150

提交評論