天堂国产午夜亚洲专区-少妇人妻综合久久蜜臀-国产成人户外露出视频在线-国产91传媒一区二区三区

當(dāng)前位置:主頁 > 論文百科 > 核心期刊 >

Windows平臺下的多線程編程

發(fā)布時間:2016-07-29 18:02

  本文關(guān)鍵詞:windows多線程編程,由筆耕文化傳播整理發(fā)布。


  線程是進程的一條執(zhí)行路徑,它包含獨立的堆棧和CPU寄存器狀態(tài),每個線程共享所有的進程資源,包括打開的文件、信號標(biāo)識及動態(tài)分配的內(nèi)存等。一個進程內(nèi)的所有線程使用同一個地址空間,而這些線程的執(zhí)行由系統(tǒng)調(diào)度程序控制,調(diào)度程序決定哪個線程可執(zhí)行以及什么時候執(zhí)行線程。線程有優(yōu)先級別,優(yōu)先權(quán)較低的線程必須等到優(yōu)先權(quán)較高的線程執(zhí)行完后再執(zhí)行。在多處理器的機器上,調(diào)度程序可將多個線程放到不同的處理器上去運行,這樣可使處理器任務(wù)平衡,并提高系統(tǒng)的運行效率。

  Windows是一種多任務(wù)的操作系統(tǒng),在Windows的一個進程內(nèi)包含一個或多個線程。32位Windows環(huán)境下的Win32 API提供了多線程應(yīng)用程序開發(fā)所需要的接口函數(shù),而利用VC中提供的標(biāo)準(zhǔn)C庫也可以開發(fā)多線程應(yīng)用程序,相應(yīng)的MFC類庫封裝了多線程編程的類,用戶在開發(fā)時可根據(jù)應(yīng)用程序的需要和特點選擇相應(yīng)的工具。為了使大家能全面地了解windows多線程編程技術(shù),本文將重點介紹Win32 API和MFC兩種方式下如何編制多線程程序。

  多線程編程在Win32方式下和MFC類庫支持下的原理是一致的,進程的主線程在任何需要的時候都可以創(chuàng)建新的線程。當(dāng)線程執(zhí)行完后,自動終止線程; 當(dāng)進程結(jié)束后,所有的線程都終止。所有活動的線程共享進程的資源,因此,在編程時需要考慮在多個線程訪問同一資源時產(chǎn)生沖突的問題。當(dāng)一個線程正在訪問某進程對象,而另一個線程要改變該對象,就可能會產(chǎn)生錯誤的結(jié)果,編程時要解決這個沖突。

Win32 API下的多線程編程

  Win32 API是Windows操作系統(tǒng)內(nèi)核與應(yīng)用程序之間的界面,它將內(nèi)核提供的功能進行函數(shù)包裝,應(yīng)用程序通過調(diào)用相關(guān)函數(shù)而獲得相應(yīng)的系統(tǒng)功能。為了向應(yīng)用程序提供多線程功能,Win32 API函數(shù)集中提供了一些處理多線程程序的函數(shù)集。直接用Win32 API進行程序設(shè)計具有很多優(yōu)點: 基于Win32的應(yīng)用程序執(zhí)行代碼小,運行效率高,但是它要求程序員編寫的代碼較多,且需要管理所有系統(tǒng)提供給程序的資源。用Win32 API直接編寫程序要求程序員對Windows系統(tǒng)內(nèi)核有一定的了解,會占用程序員很多時間對系統(tǒng)資源進行管理,因而程序員的工作效率降低。

  1. 用Win32函數(shù)創(chuàng)建和終止線程

  Win32函數(shù)庫中提供了操作多線程的函數(shù),包括創(chuàng)建線程、終止線程、建立互斥區(qū)等。在應(yīng)用程序的主線程或者其他活動線程中創(chuàng)建新的線程的函數(shù)如下:

  HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);

  如果創(chuàng)建成功則返回線程的句柄,否則返回NULL。創(chuàng)建了新的線程后,該線程就開始啟動執(zhí)行了。但如果在dwCreationFlags中使用了CREATE_SUSPENDED特性,那么線程并不馬上執(zhí)行,而是先掛起,等到調(diào)用ResumeThread后才開始啟動線程,在這個過程中可以調(diào)用下面這個函數(shù)來設(shè)置線程的優(yōu)先權(quán):   

  BOOL SetThreadPriority(HANDLE hThread,int nPriority);

  當(dāng)調(diào)用線程的函數(shù)返回后,線程自動終止。如果需要在線程的執(zhí)行過程中終止則可調(diào)用函數(shù):

  VOID ExitThread(DWORD dwExitCode);

  如果在線程的外面終止線程,則可調(diào)用下面的函數(shù):

  BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

  但應(yīng)注意: 該函數(shù)可能會引起系統(tǒng)不穩(wěn)定,而且線程所占用的資源也不釋放。因此,一般情況下,建議不要使用該函數(shù)。

  如果要終止的線程是進程內(nèi)的最后一個線程,則線程被終止后相應(yīng)的進程也應(yīng)終止。

  2. 線程的同步

  在線程體內(nèi),如果該線程完全獨立,與其他線程沒有數(shù)據(jù)存取等資源操作上的沖突,則可按照通常單線程的方法進行編程。但是,在多線程處理時情況常常不是這樣,線程之間經(jīng)常要同時訪問一些資源。由于對共享資源進行訪問引起沖突是不可避免的,為了解決這種線程同步問題,Win32 API提供了多種同步控制對象來幫助程序員解決共享資源訪問沖突。在介紹這些同步對象之前先介紹一下等待函數(shù),因為所有控制對象的訪問控制都要用到這個函數(shù)。

  Win32 API提供了一組能使線程阻塞其自身執(zhí)行的等待函數(shù)。這些函數(shù)在其參數(shù)中的一個或多個同步對象產(chǎn)生了信號,或者超過規(guī)定的等待時間才會返回。在等待函數(shù)未返回時,線程處于等待狀態(tài),此時線程只消耗很少的CPU時間。使用等待函數(shù)既可以保證線程的同步,又可以提高程序的運行效率。最常用的等待函數(shù)是:  

  DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);

  而函數(shù)WaitForMultipleObject可以用來同時監(jiān)測多個同步對象,該函數(shù)的聲明為:

  DWORD WaitForMultipleObject(DWORD nCount,CONST HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds);

  (1)互斥體對象

  Mutex對象的狀態(tài)在它不被任何線程擁有時才有信號,而當(dāng)它被擁有時則無信號。Mutex對象很適合用來協(xié)調(diào)多個線程對共享資源的互斥訪問。可按下列步驟使用該對象:

  首先,建立互斥體對象,得到句柄:

  HANDLE CreateMutex();

  然后,在線程可能產(chǎn)生沖突的區(qū)域前(即訪問共享資源之前)調(diào)用WaitForSingleObject,將句柄傳給函數(shù),請求占用互斥對象:

  dwWaitResult = WaitForSingleObject(hMutex,5000L);

  共享資源訪問結(jié)束,釋放對互斥體對象的占用:

  ReleaseMutex(hMutex);

  互斥體對象在同一時刻只能被一個線程占用,當(dāng)互斥體對象被一個線程占用時,若有另一線程想占用它,則必須等到前一線程釋放后才能成功。

 。2)信號對象   

  信號對象允許同時對多個線程共享資源進行訪問,在創(chuàng)建對象時指定最大可同時訪問的線程數(shù)。當(dāng)一個線程申請訪問成功后,信號對象中的計數(shù)器減一,調(diào)用ReleaseSemaphore函數(shù)后,信號對象中的計數(shù)器加一。其中,計數(shù)器值大于或等于0,但小于或等于創(chuàng)建時指定的最大值。如果一個應(yīng)用在創(chuàng)建一個信號對象時,將其計數(shù)器的初始值設(shè)為0,就阻塞了其他線程,保護了資源。等初始化完成后,調(diào)用ReleaseSemaphore函數(shù)將其計數(shù)器增加至最大值,則可進行正常的存取訪問?砂聪铝胁襟E使用該對象:

  首先,創(chuàng)建信號對象:

  HANDLE CreateSemaphore();

  或者打開一個信號對象:

  HANDLE OpenSemaphore();

  然后,在線程訪問共享資源之前調(diào)用WaitForSingleObject。

  共享資源訪問完成后,應(yīng)釋放對信號對象的占用:

  ReleaseSemaphore();

 。3)事件對象

  事件對象(Event)是最簡單的同步對象,它包括有信號和無信號兩種狀態(tài)。在線程訪問某一資源之前,需要等待某一事件的發(fā)生,這時用事件對象最合適。例如:只有在通信端口緩沖區(qū)收到數(shù)據(jù)后,監(jiān)視線程才被激活。

  事件對象是用CreateEvent函數(shù)建立的。該函數(shù)可以指定事件對象的類和事件的初始狀態(tài)。如果是手工重置事件,那么它總是保持有信號狀態(tài),直到用ResetEvent函數(shù)重置成無信號的事件。如果是自動重置事件,那么它的狀態(tài)在單個等待線程釋放后會自動變?yōu)闊o信號的。用SetEvent可以把事件對象設(shè)置成有信號狀態(tài)。在建立事件時,可以為對象命名,這樣其他進程中的線程可以用OpenEvent函數(shù)打開指定名字的事件對象句柄。

 。4)排斥區(qū)對象   

  在排斥區(qū)中異步執(zhí)行時,它只能在同一進程的線程之間共享資源處理。雖然此時上面介紹的幾種方法均可使用,但是,使用排斥區(qū)的方法則使同步管理的效率更高。

  使用時先定義一個CRITICAL_SECTION結(jié)構(gòu)的排斥區(qū)對象,在進程使用之前調(diào)用如下函數(shù)對對象進行初始化:

  VOID InitializeCriticalSection(LPCRITICAL_SECTION);

  當(dāng)一個線程使用排斥區(qū)時,調(diào)用函數(shù):EnterCriticalSection或者TryEnterCriticalSection;

  當(dāng)要求占用、退出排斥區(qū)時,調(diào)用函數(shù)LeaveCriticalSection,釋放對排斥區(qū)對象的占用,供其他線程使用。

  基于MFC的多線程編程

  MFC是微軟的VC開發(fā)集成環(huán)境中提供給程序員的基礎(chǔ)函數(shù)庫,它用類庫的方式將Win32 API進行封裝,以類的方式提供給開發(fā)者。由于其快速、簡捷、功能強大等特點深受廣大開發(fā)者喜愛。因此,,建議使用MFC類庫進行應(yīng)用程序的開發(fā)。   

  在VC++附帶的MFC類庫中,提供了對多線程編程的支持,基本原理與基于Win32 API的設(shè)計一致,但由于MFC對同步對象做了封裝,因此實現(xiàn)起來更加方便,避免了對象句柄管理上的煩瑣工作。

  在MFC中,線程分為兩種:工作線程和用戶接口線程。工作線程與前面所述的線程一致,用戶接口線程是一種能夠接收用戶的輸入、處理事件和消息的線程。

  1. 工作線程  

  工作線程編程較為簡單,設(shè)計思路與前面所講的基本一致: 一個基本函數(shù)代表了一個線程,創(chuàng)建并啟動線程后,線程進入運行狀態(tài); 如果線程用到共享資源,則需要進行資源同步處理。這種方式創(chuàng)建線程并啟動線程時可調(diào)用函數(shù):

  CWinThread*AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam,int nPriority= THREAD_PRIORITY_NORMAL,UINT nStackSize =0,DWORD dwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);參數(shù)pfnThreadProc是線程執(zhí)行體函數(shù),函數(shù)原形為: UINT ThreadFunction( LPVOID pParam)。

  參數(shù)pParam是傳遞給執(zhí)行函數(shù)的參數(shù); <


  本文關(guān)鍵詞:windows多線程編程,由筆耕文化傳播整理發(fā)布。



本文編號:78426

資料下載
論文發(fā)表

本文鏈接:http://www.sikaile.net/wenshubaike/jyzy/78426.html


Copyright(c)文論論文網(wǎng)All Rights Reserved | 網(wǎng)站地圖 |

版權(quán)申明:資料由用戶60e0d***提供,本站僅收錄摘要或目錄,作者需要刪除請E-mail郵箱bigeng88@qq.com