青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

franksunny的個人技術空間
獲得人生中的成功需要的專注與堅持不懈多過天才與機會。 ——C.W. Wendte

雖然自己用多線程編程用過一陣子,但是未曾仔細了解過概念,用的也是亂亂的,今天看到一篇線程總結的文章,感覺講的很好,Windows下的多線程也就是了解了線程的概念然后加一同步代碼就行了。

Windows平臺下的多線程編程

?

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

Windows 是一種多任務的操作系統,在 Windows 的一個進程內包含一個或多個線程。 32 Windows 環境下的 Win32 API 提供了多線程應用程序開發所需要的接口函數,而利用VC中提供的標準C庫也可以開發多線程應用程序,相應的MFC類庫封裝了多線程編程的類,用戶在開發時可根據應用程序的需要和特點選擇相應的工具。為了使大家能全面地了解 Windows 多線程編程技術,本文將重點介紹 Win32 API MFC 兩種方式下如何編制多線程程序。

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

?

Win32 API 下的多線程編程

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

?

1. Win32 函數創建和終止線程

Win32 函數庫中提供了操作多線程的函數,包括創建線程、終止線程、建立互斥區等。在應用程序的主線程或者其他活動線程中創建新的線程的函數如下:

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

如果創建成功則返回線程的句柄,否則返回 NULL 。創建了新的線程后,該線程就開始啟動執行了。但如果在 dwCreationFlags 中使用了 CREATE_SUSPENDED 特性,那么線程并不馬上執行,而是先掛起,等到調用 ResumeThread 后才開始啟動線程,在這個過程中可以調用下面這個函數來設置線程的優先權:

BOOL SetThreadPriority(HANDLE hThread,int nPriority);

當調用線程的函數返回后,線程自動終止。如果需要在線程的執行過程中終止則可調用函數:

VOID ExitThread(DWORD dwExitCode);

如果在線程的外面終止線程,則可調用下面的函數:

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

但應注意 : 該函數可能會引起系統不穩定,而且線程所占用的資源也不釋放。因此,一般情況下,建議不要使用該函數。

如果要終止的線程是進程內的最后一個線程,則線程被終止后相應的進程也應終止。

?

2. 線程的同步

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

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

DWORD WaitForSingleObject(HANDLE hHandle DWORD dwMilliseconds);

而函數 WaitForMultipleObject 可以用來同時監測多個同步對象,該函數的聲明為:

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

1 )互斥體對象

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

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

HANDLE CreateMutex();

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

dwWaitResult = WaitForSingleObject(hMutex,5000L);

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

ReleaseMutex(hMutex);

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

?

2 )信號對象

信號對象允許同時對多個線程共享資源進行訪問,在創建對象時指定最大可同時訪問的線程數。當一個線程申請訪問成功后,信號對象中的計數器減一,調用 ReleaseSemaphore 函數后,信號對象中的計數器加一。其中,計數器值大于或等于0,但小于或等于創建時指定的最大值。如果一個應用在創建一個信號對象時,將其計數器的初始值設為0,就阻塞了其他線程,保護了資源。等初始化完成后,調用 ReleaseSemaphore 函數將其計數器增加至最大值,則可進行正常的存取訪問。可按下列步驟使用該對象:

首先,創建信號對象:

HANDLE CreateSemaphore();

或者打開一個信號對象:

HANDLE OpenSemaphore();

然后,在線程訪問共享資源之前調用 WaitForSingleObject

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

ReleaseSemaphore();

3 )事件對象

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

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

4 )排斥區對象

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

使用時先定義一個 CR99vICAL_SECTION 結構的排斥區對象,在進程使用之前調用如下函數對對象進行初始化 :

VOID InitializeCriticalSection( LPCRITICAL_SECTION );

當一個線程使用排斥區時,調用函數: EnterCriticalSection 或者 TryEnterCriticalSection;

當要求占用、退出排斥區時,調用函數 LeaveCriticalSection ,釋放對排斥區對象的占用,供其他線程使用。

?

基于MFC的多線程編程

?

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

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

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

1. 工作線程

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

CWinThread*AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam,int nPriority= THREAD_PRIOR ITY _NORMAL,UINT nStackSize =0,DWORD dwCreateFlags=0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

參數 pfnThreadProc 是線程執行體函數,函數原形為 : UINT ThreadFunction( LPVOID pParam)

參數 pParam 是傳遞給執行函數的參數;

參數 nPriority 是線程執行權限,可選值:

THREAD_PRIOR ITY _NORMAL THREAD_PRIOR ITY _LOWEST THREAD_PRIOR ITY _HIGHEST THREAD_PRIOR ITY _IDLE

參數 dwCreateFlags 是線程創建時的標志,可取值 CREATE_SUSPENDED ,表示線程創建后處于掛起狀態,調用 ResumeThread 函數后線程繼續運行,或者取值 0” 表示線程創建后處于運行狀態。

返回值是 CWinThread 類對象指針,它的成員變量 m_hThread 為線程句柄,在 Win32 API 方式下對線程操作的函數參數都要求提供線程的句柄,所以當線程創建后可以使用所有 Win32 API 函數對 pWinThread->m_Thread 線程進行相關操作。

?

注意:如果在一個類對象中創建和啟動線程時,應將線程函數定義成類外的全局函數。 (這句話是否必要,我也不清楚)

?

2. 用戶接口線程

基于 MFC 的應用程序有一個應用對象,它是 CWinApp 派生類的對象,該對象代表了應用進程的主線程。當線程執行完并退出線程時,由于進程中沒有其他線程存在,進程自動結束。類 C inApp C inThread 派生出來, C inThread 是用戶接口線程的基本類。我們在編寫用戶接口線程時,需要從 C inThread 派生我們自己的線程類, ClassWizard 可以幫助我們完成這個工作。

先用 ClassWizard 派生一個新的類,設置基類為 CwinThread 。注意:類的 DECLARE_DYNCREATE IMPLEMENT_DYNCREATE 宏是必需的,因為創建線程時需要動態創建類的對象。根據需要可將初始化和結束代碼分別放在類的 InitInstance ExitInstance 函數中。如果需要創建窗口,則可在 InitInstance 函數中完成。然后創建線程并啟動線程。可以用兩種方法來創建用戶接口線程, MFC 提供了兩個版本的 AfxBeginThread 函數,其中一個用于創建用戶接口線程。第二種方法分為兩步進行:首先,調用線程類的構造函數創建一個線程對象;其次,調用 CWinThread::CreateThread 函數來創建該線程。線程建立并啟動后,在線程函數執行過程中一直有效。如果是線程對象,則在對象刪除之前,先結束線程。 CWinThread 已經為我們完成了線程結束的工作。

?

3. 線程同步

前面我們介紹了 Win32 API 提供的幾種有關線程同步的對象,在 MFC 類庫中對這幾個對象進行了類封裝,它們有一個共同的基類 CSyncObject ,它們的對應關系為 : Semaphore 對應 CSemaphore Mutex 對應 CMutex Event 對應 CEvent CriticalSection 對應 CCriticalSection 。另外, MFC 對兩個等待函數也進行了封裝,即 CSingleLock CMultiLock 。因四個對象用法相似,在這里就以 CMutex 為例進行說明:

創建一個 CMutex 對象 :

CMutex mutex(FALSE,NULL,NULL); CMutex mutex;

當各線程要訪問共享資源時使用下面代碼:

CSingleLock sl(&mutex);

sl.Lock();

if(sl.IsLocked())

// 對共享資源進行操作 ...

sl.Unlock();

?

結束語

如果用戶的應用程序需要多個任務同時進行相應的處理,則使用多線程是較理想的選擇。這里,提醒大家注意的是在多線程編程時要特別小心處理資源共享問題以及多線程調試問題。筆者準備了幾個實例,如大家需要的話,可以和筆者聯系。

posted on 2007-01-26 22:10 frank.sunny 閱讀(2553) 評論(0)  編輯 收藏 引用 所屬分類: MFC相關技術

常用鏈接

留言簿(13)

隨筆分類

個人其它博客

基礎知識鏈接

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久婷婷国产综合国色天香| 亚洲午夜精品视频| 久久久欧美精品| 欧美在线播放视频| 极品少妇一区二区| 亚洲国产精品悠悠久久琪琪 | 欧美另类极品videosbest最新版本| 在线观看日韩专区| 亚洲国产精品高清久久久| 欧美日韩小视频| 欧美一区二区三区在线免费观看 | 欧美r片在线| 欧美剧在线观看| 午夜精品美女久久久久av福利| 亚洲欧美日韩中文视频| 黄色精品一区二区| 亚洲美洲欧洲综合国产一区| 国产精品高潮呻吟久久av黑人| 久久国产日韩欧美| 欧美成人精品一区| 亚洲一区影音先锋| 免费成人你懂的| 午夜精品视频在线观看| 久久中文字幕一区| 亚洲自拍偷拍福利| 裸体素人女欧美日韩| 欧美亚洲视频| 欧美激情1区2区| 麻豆久久婷婷| 国产伦精品一区二区三区四区免费| 另类天堂视频在线观看| 国产精品v日韩精品| 免费视频一区| 国产欧美日韩高清| 亚洲免费播放| 亚洲黄色一区| 久久av一区二区三区漫画| 一区二区三区欧美在线| 久久综合中文| 久久国产精品亚洲va麻豆| 欧美日本高清| 亚洲电影下载| 亚洲国产精品va在线看黑人动漫 | 久久久久久一区| 国产精品久久国产愉拍| 亚洲人妖在线| 日韩视频欧美视频| 美女精品自拍一二三四| 久久久久久久久综合| 国产精品入口夜色视频大尺度| 亚洲国产欧美不卡在线观看| 狠狠色伊人亚洲综合网站色| 午夜精品美女自拍福到在线| 亚洲香蕉网站| 欧美日韩亚洲在线| 免费欧美在线视频| 亚洲电影视频在线| 久久视频国产精品免费视频在线| 久久国产99| 国产日韩综合一区二区性色av| 亚洲性感美女99在线| 亚洲嫩草精品久久| 国产精品久久久久影院亚瑟 | 欧美一区二区精品| 久久精品中文字幕一区二区三区| 国产精品国内视频| 亚洲尤物精选| 欧美中文在线字幕| 久久综合色一综合色88| 欧美成人免费一级人片100| 在线观看一区| 欧美大片在线影院| 亚洲免费成人av| 亚洲欧美日韩一区二区在线| 国产精品久久999| 欧美一区二区三区在线观看视频 | 亚洲精选中文字幕| 欧美日韩精品一区| 亚洲视频在线视频| 久久一区二区三区av| 亚洲第一精品福利| 欧美激情综合网| 亚洲视频在线一区| 久久久久久久一区二区| 亚洲国产视频直播| 欧美午夜精品久久久久久人妖| 亚洲一区三区视频在线观看| 久久久久久久久久久一区 | 国产精品久久婷婷六月丁香| 先锋影音久久| 欧美国产亚洲精品久久久8v| 一区二区三区久久精品| 国产亚洲精品bv在线观看| 久久免费国产| 日韩一级精品视频在线观看| 欧美一区二区免费观在线| 在线日韩日本国产亚洲| 国产精品国产| 嫩草伊人久久精品少妇av杨幂| 一本色道88久久加勒比精品| 久久蜜桃资源一区二区老牛| 一本色道久久88精品综合| 国产欧美日韩| 欧美伦理一区二区| 亚洲欧美偷拍卡通变态| 亚洲区一区二| 久久婷婷av| 香蕉成人伊视频在线观看| 亚洲国产精品123| 国产丝袜美腿一区二区三区| 欧美日韩国产精品| 久久久亚洲国产美女国产盗摄| 一区二区免费在线播放| 蜜臀av在线播放一区二区三区| 午夜精品美女自拍福到在线 | 影音先锋中文字幕一区| 国产精品视频在线观看| 欧美激情精品久久久久久| 香蕉久久国产| 亚洲在线日韩| 一本色道久久88亚洲综合88| 你懂的亚洲视频| 久久久99精品免费观看不卡| 亚洲欧美视频| 亚洲一区二区成人| 亚洲美女精品成人在线视频| 亚洲成人原创| 在线成人免费视频| 黑丝一区二区三区| 国产亚洲午夜| 国产一区二区三区成人欧美日韩在线观看 | 亚洲二区在线视频| 国内成人在线| 久久影视三级福利片| 午夜精品久久久久久久白皮肤| 99精品久久久| 亚洲精品在线观看视频| 欧美国产综合视频| 免费日韩成人| 欧美激情中文字幕在线| 欧美大片va欧美在线播放| 嫩草国产精品入口| 欧美国产日韩a欧美在线观看| 久久综合久久久| 久久综合中文| 美乳少妇欧美精品| 亚洲福利视频免费观看| 欧美黄色大片网站| 亚洲精品视频在线观看免费| 亚洲国产精品一区在线观看不卡| 亚洲国产精品一区二区久| 亚洲人www| 中文国产成人精品久久一| 亚洲一区二区三区中文字幕在线| 亚洲一区二区三区四区在线观看 | 欧美日韩在线播放一区| 国产精品日韩专区| 国产人成精品一区二区三| 国语自产在线不卡| 亚洲高清色综合| 在线亚洲高清视频| 久久成人免费视频| 欧美激情在线狂野欧美精品| 亚洲电影下载| 亚洲性图久久| 久久伊人一区二区| 欧美精品粉嫩高潮一区二区 | 欧美日韩一区二区三区免费| 国产精品久久久久久久久果冻传媒 | 黄色日韩网站| 99riav国产精品| 欧美亚洲一区二区三区| 免费视频一区| 亚洲深夜福利视频| 久久人人97超碰人人澡爱香蕉 | 午夜国产欧美理论在线播放| 久久久7777| 欧美色视频一区| 在线成人av.com| 亚洲综合色在线| 欧美国产亚洲精品久久久8v| 亚洲一区在线免费| 美日韩免费视频| 国产亚洲精品福利| 一区二区高清在线观看| 老牛影视一区二区三区| 日韩一二三区视频| 麻豆av一区二区三区久久| 国产精品乱码人人做人人爱| 亚洲欧洲在线看| 久久久久国产精品厨房| 亚洲最黄网站| 蜜乳av另类精品一区二区| 国产精品一区二区你懂得| 亚洲精品一区二区三区蜜桃久| 西西人体一区二区| 亚洲最黄网站| 欧美日韩黄视频| 亚洲日本理论电影| 免费视频一区二区三区在线观看|