欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
第八章 MFC的進(jìn)程和線(xiàn)程
  1. MFC的進(jìn)程和線(xiàn)程

     

    1. Win32的進(jìn)程和線(xiàn)程概念

       

進(jìn)程是一個(gè)可執行的程序,由私有虛擬地址空間、代碼、數據和其他操作系統資源(如進(jìn)程創(chuàng )建的文件、管道、同步對象等)組成。一個(gè)應用程序可以有一個(gè)或多個(gè)進(jìn)程,一個(gè)進(jìn)程可以有一個(gè)或多個(gè)線(xiàn)程,其中一個(gè)是主線(xiàn)程。

線(xiàn)程是操作系統分時(shí)調度分配CPU時(shí)間的基本實(shí)體。一個(gè)線(xiàn)程可以執行程序的任意部分的代碼,即使這部分代碼被另一個(gè)線(xiàn)程并發(fā)地執行;一個(gè)進(jìn)程的所有線(xiàn)程共享它的虛擬地址空間、全局變量和操作系統資源。

之所以有線(xiàn)程這個(gè)概念,是因為以線(xiàn)程而不是進(jìn)程為調度對象效率更高:

  • 由于創(chuàng )建新進(jìn)程必須加載代碼,而線(xiàn)程要執行的代碼已經(jīng)被映射到進(jìn)程的地址空間,所以創(chuàng )建、執行線(xiàn)程的速度比進(jìn)程更快。

     

  • 一個(gè)進(jìn)程的所有線(xiàn)程共享進(jìn)程的地址空間和全局變量,所以簡(jiǎn)化了線(xiàn)程之間的通訊。

     

    1. Win32的進(jìn)程處理簡(jiǎn)介

       

      因為MFC沒(méi)有提供類(lèi)處理進(jìn)程,所以直接使用了Win32 API函數。

      1. 進(jìn)程的創(chuàng )建

         

        調用CreateProcess函數創(chuàng )建新的進(jìn)程,運行指定的程序。CreateProcess的原型如下:

        BOOL CreateProcess(

        LPCTSTR lpApplicationName,

        LPTSTR lpCommandLine,

        LPSECURITY_ATTRIBUTES lpProcessAttributes,

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        BOOL bInheritHandles,

        DWORD dwCreationFlags,

        LPVOID lpEnvironment,

        LPCTSTR lpCurrentDirectory,

        LPSTARTUPINFO lpStartupInfo,

        LPPROCESS_INFORMATION lpProcessInformation

        );

        其中:

        lpApplicationName指向包含了要運行模塊名字的字符串。

        lpCommandLine指向命令行字符串。

        lpProcessAttributes描述進(jìn)程的安全性屬性,NT下有用。

        lpThreadAttributes描述進(jìn)程初始線(xiàn)程(主線(xiàn)程)的安全性屬性,NT下有用。

        bInHeritHandles表示子進(jìn)程(被創(chuàng )建的進(jìn)程)是否可以繼承父進(jìn)程的句柄??梢岳^承的句柄有線(xiàn)程句柄、有名或無(wú)名管道、互斥對象、事件、信號量、映像文件、普通文件和通訊端口等;還有一些句柄不能被繼承,如內存句柄、DLL實(shí)例句柄、GDI句柄、URER句柄等等。

        子進(jìn)程繼承的句柄由父進(jìn)程通過(guò)命令行方式或者進(jìn)程間通訊(IPC)方式由父進(jìn)程傳遞給它。

        dwCreationFlags表示創(chuàng )建進(jìn)程的優(yōu)先級類(lèi)別和進(jìn)程的類(lèi)型。創(chuàng )建進(jìn)程的類(lèi)型分控制臺進(jìn)程、調試進(jìn)程等;優(yōu)先級類(lèi)別用來(lái)控制進(jìn)程的優(yōu)先級別,分Idle、Normal、High、Real_time四個(gè)類(lèi)別。

        lpEnviroment指向環(huán)境變量塊,環(huán)境變量可以被子進(jìn)程繼承。

        lpCurrentDirectory指向表示當前目錄的字符串,當前目錄可以繼承。

        lpStartupInfo指向StartupInfo結構,控制進(jìn)程的主窗口的出現方式。

        lpProcessInformation指向PROCESS_INFORMATION結構,用來(lái)存儲返回的進(jìn)程信息。

        從其參數可以看出創(chuàng )建一個(gè)新的進(jìn)程需要指定什么信息。

        從上面的解釋可以看出,一個(gè)進(jìn)程包含了很多信息。若進(jìn)程創(chuàng )建成功的話(huà),返回一個(gè)進(jìn)程信息結構類(lèi)型的指針。進(jìn)程信息結構如下:

        typedef struct _PROCESS_INFORMATION {

        HANDLE hProcess;

        HANDLE hThread;

        DWORD dwProcessId;

        DWORD dwThreadId;

        }PROCESS_INFORMATION;

        進(jìn)程信息結構包括進(jìn)程句柄,主線(xiàn)程句柄,進(jìn)程ID,主線(xiàn)程ID。

      2. 進(jìn)程的終止

         

進(jìn)程在以下情況下終止:

  • 調用ExitProcess結束進(jìn)程;

     

  • 進(jìn)程的主線(xiàn)程返回,隱含地調用ExitProcess導致進(jìn)程結束;

     

  • 進(jìn)程的最后一個(gè)線(xiàn)程終止;

     

  • 調用TerminateProcess終止進(jìn)程。

     

  • 當要結束一個(gè)GDI進(jìn)程時(shí),發(fā)送WM_QUIT消息給主窗口,當然也可以從它的任一線(xiàn)程調用ExitProcess。

     

    1. Win32的線(xiàn)程

       

      1. 線(xiàn)程的創(chuàng )建

         

使用CreateThread函數創(chuàng )建線(xiàn)程,CreateThread的原型如下:

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags, // creation flags

LPDWORD lpThreadId

);

其中:

lpThreadAttributes表示創(chuàng )建線(xiàn)程的安全屬性,NT下有用。

dwStackSize指定線(xiàn)程棧的尺寸,如果為0則與進(jìn)程主線(xiàn)程棧相同。

lpStartAddress指定線(xiàn)程開(kāi)始運行的地址。

lpParameter表示傳遞給線(xiàn)程的32位的參數。

dwCreateFlages表示是否創(chuàng )建后掛起線(xiàn)程(取值CREATE_SUSPEND),掛起后調用ResumeThread繼續執行。

lpThreadId用來(lái)存放返回的線(xiàn)程ID。

  • 線(xiàn)程的優(yōu)先級別

     

進(jìn)程的每個(gè)優(yōu)先級類(lèi)包含了五個(gè)線(xiàn)程的優(yōu)先級水平。在進(jìn)程的優(yōu)先級類(lèi)確定之后,可以改變線(xiàn)程的優(yōu)先級水平。用SetPriorityClass設置進(jìn)程優(yōu)先級類(lèi),用SetThreadPriority設置線(xiàn)程優(yōu)先級水平。

Normal級的線(xiàn)程可以被除了Idle級以外的任意線(xiàn)程搶占。

      1. 線(xiàn)程的終止

         

以下情況終止一個(gè)線(xiàn)程:

  • 調用了ExitThread函數;

     

  • 線(xiàn)程函數返回:主線(xiàn)程返回導致ExitProcess被調用,其他線(xiàn)程返回導致ExitThread被調用;

     

  • 調用ExitProcess導致進(jìn)程的所有線(xiàn)程終止;

     

  • 調用TerminateThread終止一個(gè)線(xiàn)程;

     

  • 調用TerminateProcess終止一個(gè)進(jìn)程時(shí),導致其所有線(xiàn)程的終止。

     

當用TerminateProcess或者TerminateThread終止進(jìn)程或線(xiàn)程時(shí),DLL的入口函數DllMain不會(huì )被執行(如果有DLL的話(huà))。

      1. 線(xiàn)程局部存儲

         

如果希望每個(gè)線(xiàn)程都可以有線(xiàn)程局部(Thread local)的靜態(tài)存儲數據,可以使用TLS線(xiàn)程局部存儲技術(shù)。TLS為進(jìn)程分配一個(gè)TLS索引,進(jìn)程的每個(gè)線(xiàn)程通過(guò)這個(gè)索引存取自己的數據變量的拷貝。

TLS對DLL是非常有用的。當一個(gè)新的進(jìn)程使用DLL時(shí),在DLL入口函數DllMain中使用TlsAlloc分配TLS索引,TLS索引就作為進(jìn)程私有的全局變量被保存;以后,當該進(jìn)程的新的線(xiàn)程使用DLL時(shí)(Attahced to DLL),DllMain給它分配動(dòng)態(tài)內存并且使用TlsSetValue把線(xiàn)程私有的數據按索引保存。DLL函數可以使用TlsGetValue按索引讀取調用線(xiàn)程的私有數據。

TLS函數如下:

  • DWORD TlsAlloc()

     

在進(jìn)程或DLL初始化時(shí)調用,并且把返回值(索引值)作為全局變量保存。

  • BOOL TlsSetValue(

     

DWORD dwTlsIndex, //TLS index to set value for

LPVOID lpTlsValue //value to be stored

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

lpTlsValue是線(xiàn)程在TLS槽中存放的數據指針,指針指向線(xiàn)程要保存的數據。

線(xiàn)程首先分配動(dòng)態(tài)內存并保存數據到此內存中,然后調用TlsSetValue保存內存指針到TLS槽。

  • LPVOID TlsGetValue(

     

DWORD dwTlsIndex // TLS index to retrieve value for

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

當要存取保存的數據時(shí),使用索引得到數據指針。

  • BOOL TlsFree(

     

DWORD dwTlsIndex // TLS index to free

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

當每一個(gè)線(xiàn)程都不再使用局部存儲數據時(shí),線(xiàn)程釋放它分配的動(dòng)態(tài)內存。在TLS索引不再需要時(shí),使用TlsFree釋放索引。

    1. 線(xiàn)程同步

       

      同步可以保證在一個(gè)時(shí)間內只有一個(gè)線(xiàn)程對某個(gè)資源(如操作系統資源等共享資源)有控制權。共享資源包括全局變量、公共數據成員或者句柄等。同步還可以使得有關(guān)聯(lián)交互作用的代碼按一定的順序執行。

      Win32提供了一組對象用來(lái)實(shí)現多線(xiàn)程的同步。

      這些對象有兩種狀態(tài):獲得信號(Signaled)或者沒(méi)有或則信號(Not signaled)。線(xiàn)程通過(guò)Win32 API提供的同步等待函數(Wait functions)來(lái)使用同步對象。一個(gè)同步對象在同步等待函數調用時(shí)被指定,調用同步函數地線(xiàn)程被阻塞(blocked),直到同步對象獲得信號。被阻塞的線(xiàn)程不占用CPU時(shí)間。

      1. 同步對象

         

同步對象有:Critical_section(關(guān)鍵段),Event(事件),Mutex(互斥對象),Semaphores(信號量)。

下面,解釋怎么使用這些同步對象。

  1. 關(guān)鍵段對象:

     

    首先,定義一個(gè)關(guān)鍵段對象cs:

    CRITICAL_SECTION cs;

    然后,初始化該對象。初始化時(shí)把對象設置為NOT_SINGALED,表示允許線(xiàn)程使用資源:

    InitializeCriticalSection(&cs);

    如果一段程序代碼需要對某個(gè)資源進(jìn)行同步保護,則這是一段關(guān)鍵段代碼。在進(jìn)入該關(guān)鍵段代碼前調用EnterCriticalSection函數,這樣,其他線(xiàn)程都不能執行該段代碼,若它們試圖執行就會(huì )被阻塞。

    完成關(guān)鍵段的執行之后,調用LeaveCriticalSection函數,其他的線(xiàn)程就可以繼續執行該段代碼。如果該函數不被調用,則其他線(xiàn)程將無(wú)限期的等待。

  2. 事件對象

     

    首先,調用CreateEvent函數創(chuàng )建一個(gè)事件對象,該函數返回一個(gè)事件句柄。然后,可以設置(SetEvent)或者復位(ResetEvent)一個(gè)事件對象,也可以發(fā)一個(gè)事件脈沖(PlusEvent),即設置一個(gè)事件對象,然后復位它。復位有兩種形式:自動(dòng)復位和人工復位。在創(chuàng )建事件對象時(shí)指定復位形式。。

    自動(dòng)復位:當對象獲得信號后,就釋放下一個(gè)可用線(xiàn)程(優(yōu)先級別最高的線(xiàn)程;如果優(yōu)先級別相同,則等待隊列中的第一個(gè)線(xiàn)程被釋放)。

    人工復位:當對象獲得信號后,就釋放所有可利用線(xiàn)程。

    最后,使用CloseHandle銷(xiāo)毀創(chuàng )建的事件對象。

  3. 互斥對象

     

    首先,調用CreateMutex創(chuàng )建互斥對象;然后,調用等待函數,可以的話(huà)利用關(guān)鍵資源;最后,調用RealseMutex釋放互斥對象。

    互斥對象可以在進(jìn)程間使用,但關(guān)鍵段對象只能用于同一進(jìn)程的線(xiàn)程之間。

  4. 信號量對象

     

    在Win32中,信號量的數值變?yōu)?時(shí)給以信號。在有多個(gè)資源需要管理時(shí)可以使用信號量對象。

    首先,調用CreateSemaphore創(chuàng )建一個(gè)信號量;然后,調用等待函數,如果允許的話(huà),則利用關(guān)鍵資源;最后,調用RealeaseSemaphore釋放信號量對象。

  5. 此外,還有其他句柄可以用來(lái)同步線(xiàn)程:

     

文件句柄(FILE HANDLES)

命名管道句柄(NAMED PIPE HANDELS)

控制臺輸入緩沖區句柄(CONSOLE INPUT BUFFER HANDLES)

通訊設備句柄(COMMUNICTION DEVICE HANDLES)

進(jìn)程句柄(PROCESS HANDLES)

線(xiàn)程句柄(THREAD HANDLES)

例如,當一個(gè)進(jìn)程或線(xiàn)程結束時(shí),進(jìn)程或線(xiàn)程句柄獲得信號,等待該進(jìn)程或者線(xiàn)程結束的線(xiàn)程被釋放。

      1. 等待函數

         

Win32提供了一組等待函數用來(lái)讓一個(gè)線(xiàn)程阻塞自己的執行。等待函數分三類(lèi):

  1. 等待單個(gè)對象的(FOR SINGLE OBJECT):

     

    這類(lèi)函數包括:

    SignalObjectAndWait

    WaitForSingleObject

    WaitForSingleObjectEx

    函數參數包括同步對象的句柄和等待時(shí)間等。

    在以下情況下等待函數返回:

    同步對象獲得信號時(shí)返回;

    等待時(shí)間達到了返回:如果等待時(shí)間不限制(Infinite),則只有同步對象獲得信號才返回;如果等待時(shí)間為0,則在測試了同步對象的狀態(tài)之后馬上返回。

  2. 等待多個(gè)對象的(FOR MULTIPLE OBJECTS)

     

    這類(lèi)函數包括:

    WaitForMultipleObjects

    WaitForMultipleObjectsEx

    MsgWaitForMultipleObjects

    MsgWaitForMultipleObjectsEx

    函數參數包括同步對象的句柄,等待時(shí)間,是等待一個(gè)還是多個(gè)同步對象等等。

    在以下情況下等待函數返回:

    一個(gè)或全部同步對象獲得信號時(shí)返回(在參數中指定是等待一個(gè)或多個(gè)同步對象);

    等待時(shí)間達到了返回:如果等待時(shí)間不限制(Infinite),則只有同步對象獲得信號才返回;如果等待時(shí)間為0,則在測試了同步對象的狀態(tài)之后馬上返回。

  3. 可以發(fā)出提示的函數(ALTERABLE)

     

這類(lèi)函數包括:

MsgWaitForMultipleObjectsEx

SignalObjectAndWait

WaitForMultipleObjectsEx

WaitForSingleObjectEx

這些函數主要用于重疊(Overlapped)的I/O(異步I/O)。

    1. MFC的線(xiàn)程處理

       

      在Win32 API的基礎之上,MFC提供了處理線(xiàn)程的類(lèi)和函數。處理線(xiàn)程的類(lèi)是CWinThread,函數是AfxBeginThread、AfxEndThread等。

      表5-6解釋了CWinThread的成員變量和函數。

      CWinThread是MFC線(xiàn)程類(lèi),它的成員變量m_hThread和m_hThreadID是對應的Win32線(xiàn)程句柄和線(xiàn)程ID。

      MFC明確區分兩種線(xiàn)程:用戶(hù)界面線(xiàn)程(User interface thread)和工作者線(xiàn)程(Worker thread)。用戶(hù)界面線(xiàn)程一般用于處理用戶(hù)輸入并對用戶(hù)產(chǎn)生的事件和消息作出應答。工作者線(xiàn)程用于完成不要求用戶(hù)輸入的任務(wù),如耗時(shí)計算。

      Win32 API并不區分線(xiàn)程類(lèi)型,它只需要知道線(xiàn)程的開(kāi)始地址以便它開(kāi)始執行線(xiàn)程。MFC為用戶(hù)界面線(xiàn)程特別地提供消息泵來(lái)處理用戶(hù)界面的事件。CWinApp對象是用戶(hù)界面線(xiàn)程對象的一個(gè)例子,CWinApp從類(lèi)CWinThread派生并處理用戶(hù)產(chǎn)生的事件和消息。

      1. 創(chuàng )建用戶(hù)界面線(xiàn)程

         

通過(guò)以下步驟創(chuàng )建一個(gè)用戶(hù)界面線(xiàn)程:

  • 從CWinThread派生一個(gè)有動(dòng)態(tài)創(chuàng )建能力的類(lèi)。使用DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE宏來(lái)支持動(dòng)態(tài)創(chuàng )建。

     

  • 覆蓋CWinThread的一些虛擬函數,可以覆蓋的函數見(jiàn)表5-4關(guān)于CWinThread的部分。其中,函數InitInstance是必須覆蓋的,ExitInstance通常是要覆蓋的。

     

  • 使用AfxBeginThread創(chuàng )建MFC線(xiàn)程對象和Win32線(xiàn)程對象。如果創(chuàng )建線(xiàn)程時(shí)沒(méi)有指定CREATE_SUSPENDED,則開(kāi)始執行線(xiàn)程。

     

  • 如果創(chuàng )建線(xiàn)程是指定了CREATE_SUSPENDED,則在適當的地方調用函數ResumeThread開(kāi)始執行線(xiàn)程。

     

      1. 創(chuàng )建工作者線(xiàn)程

         

        程序員不必從CWinThread派生新的線(xiàn)程類(lèi),只需要提供一個(gè)控制函數,由線(xiàn)程啟動(dòng)后執行該函數。

        然后,使用AfxBeginThread創(chuàng )建MFC線(xiàn)程對象和Win32線(xiàn)程對象。如果創(chuàng )建線(xiàn)程時(shí)沒(méi)有指定CREATE_SUSPENDED(創(chuàng )建后掛起),則創(chuàng )建的新線(xiàn)程開(kāi)始執行。

        如果創(chuàng )建線(xiàn)程是指定了CREATE_SUSPENDED,則在適當的地方調用函數ResumeThread開(kāi)始執行線(xiàn)程。

        雖然程序員沒(méi)有從CWinThread派生類(lèi),但是MFC給工作者線(xiàn)程提供了缺省的CWinThread對象。

      2. AfxBeginThread

         

用戶(hù)界面線(xiàn)程和工作者線(xiàn)程都是由AfxBeginThread創(chuàng )建的?,F在,考察該函數:MFC提供了兩個(gè)重載版的AfxBeginThread,一個(gè)用于用戶(hù)界面線(xiàn)程,另一個(gè)用于工作者線(xiàn)程,分別有如下的原型和過(guò)程:

  1. 用戶(hù)界面線(xiàn)程的AfxBeginThread

     

    用戶(hù)界面線(xiàn)程的AfxBeginThread的原型如下:

    CWinThread* AFXAPI AfxBeginThread(

    CRuntimeClass* pThreadClass,

    int nPriority,

    UINT nStackSize,

    DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs)

    其中:

    參數1是從CWinThread派生的RUNTIME_CLASS類(lèi);

    參數2指定線(xiàn)程優(yōu)先級,如果為0,則與創(chuàng )建該線(xiàn)程的線(xiàn)程相同;

    參數3指定線(xiàn)程的堆棧大小,如果為0,則與創(chuàng )建該線(xiàn)程的線(xiàn)程相同;

    參數4是一個(gè)創(chuàng )建標識,如果是CREATE_SUSPENDED,則在懸掛狀態(tài)創(chuàng )建線(xiàn)程,在線(xiàn)程創(chuàng )建后線(xiàn)程掛起,否則線(xiàn)程在創(chuàng )建后開(kāi)始線(xiàn)程的執行。

    參數5表示線(xiàn)程的安全屬性,NT下有用。

  2. 工作者線(xiàn)程的AfxBeginThread

     

    工作者線(xiàn)程的AfxBeginThread的原型如下:

    CWinThread* AFXAPI AfxBeginThread(

    AFX_THREADPROC pfnThreadProc,

    LPVOID pParam,

    int nPriority,

    UINT nStackSize,

    DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs)

    其中:

    參數1指定控制函數的地址;

    參數2指定傳遞給控制函數的參數;

    參數3、4、5分別指定線(xiàn)程的優(yōu)先級、堆棧大小、創(chuàng )建標識、安全屬性,含義同用戶(hù)界面線(xiàn)程。

  3. AfxBeginThread創(chuàng )建線(xiàn)程的流程

     

不論哪個(gè)AfxBeginThread,首先都是創(chuàng )建MFC線(xiàn)程對象,然后創(chuàng )建Win32線(xiàn)程對象。在創(chuàng )建MFC線(xiàn)程對象時(shí),用戶(hù)界面線(xiàn)程和工作者線(xiàn)程的創(chuàng )建分別調用了不同的構造函數。用戶(hù)界面線(xiàn)程是從CWinThread派生的,所以,要先調用派生類(lèi)的缺省構造函數,然后調用CWinThread的缺省構造函數。圖8-1中兩個(gè)構造函數所調用的CommonConstruct是MFC內部使用的成員函數。

      1. CreateThread和_AfxThreadEntry

         

        MFC使用CWinThread::CreateThread創(chuàng )建線(xiàn)程,不論對工作者線(xiàn)程或用戶(hù)界面線(xiàn)程,都指定線(xiàn)程的入口函數是_AfxThreadEntry。_AfxThreadEntry調用AfxInitThread初始化線(xiàn)程。

        CreateThread和_AfxThreadEntry在線(xiàn)程的創(chuàng )建過(guò)程中使用同步手段交互等待、執行。CreateThread由創(chuàng )建線(xiàn)程執行,_AfxThreadEntry由被創(chuàng )建的線(xiàn)程執行,兩者通過(guò)兩個(gè)事件對象(hEvent和hEvent2)同步:

        在創(chuàng )建了新線(xiàn)程之后,創(chuàng )建線(xiàn)程將在hEvent事件上無(wú)限等待直到新線(xiàn)程給出創(chuàng )建結果;新線(xiàn)程在創(chuàng )建成功或者失敗之后,觸發(fā)事件hEvent讓父線(xiàn)程運行,并且在hEven2上無(wú)限等待直到父線(xiàn)程退出CreateThread函數;父線(xiàn)程(創(chuàng )建線(xiàn)程)因為hEvent的置位結束等待,繼續執行,退出CreateThread之前觸發(fā)hEvent2事件;新線(xiàn)程(子線(xiàn)程)因為hEvent2的置位結束等待,開(kāi)始執行控制函數(工作者線(xiàn)程)或者進(jìn)入消息循環(huán)(用戶(hù)界面線(xiàn)程)。

        MFC在線(xiàn)程創(chuàng )建中使用了如下數據結構:

        struct _AFX_THREAD_STARTUP

        {

        //傳遞給線(xiàn)程啟動(dòng)的參數(IN)

        _AFX_THREAD_STATE* pThreadState;//父線(xiàn)程的線(xiàn)程狀態(tài)

        CWinThread* pThread; //新創(chuàng )建的MFC線(xiàn)程對象

        DWORD dwCreateFlags; //線(xiàn)程創(chuàng )建標識

        _PNH pfnNewHandler; //新線(xiàn)程的句柄

        HANDLE hEvent; //同步事件,線(xiàn)程創(chuàng )建成功或失敗后置位

        HANDLE hEvent2; //同步事件,新線(xiàn)程恢復執行后置位

        //返回給創(chuàng )建線(xiàn)程的參數,在新線(xiàn)程恢復執行后賦值

        BOOL bError; //如果創(chuàng )建發(fā)生錯誤,TRUE

        };

        該結構作為線(xiàn)程開(kāi)始函數的參數被傳遞給_beginthreadex函數來(lái)創(chuàng )建和啟動(dòng)線(xiàn)程。_beginthreadex函數是“C”的線(xiàn)程創(chuàng )建函數,具有如下原型:

        unsigned long _beginthreadex(

        void *security,

        unsigned stack_size,

        unsigned ( __stdcall *start_address )( void * ),

        void *arglist,

        unsigned initflag,

        unsigned *thrdaddr );

        圖8-2描述了上述過(guò)程。圖中表示,_AfxThreadEntry在啟動(dòng)線(xiàn)程時(shí),將創(chuàng )建本線(xiàn)程的線(xiàn)程狀態(tài),并且繼承父線(xiàn)程的模塊狀態(tài)。關(guān)于MFC狀態(tài),見(jiàn)第9章。

         

         

      2. 線(xiàn)程的結束

         

        從圖8-2可以看出,AfxEndThread用來(lái)結束調用它的線(xiàn)程:它將清理本線(xiàn)程創(chuàng )建的MFC對象和釋放線(xiàn)程局部存儲分配的內存空間;調用CWinThread的虛擬函數Delete;調用“C”的結束線(xiàn)程函數_endthreadex釋放分配給線(xiàn)程的資源,但是不關(guān)閉線(xiàn)程句柄。

        CWinThread::Delete的缺省實(shí)現是:如果本線(xiàn)程的成員函數m_bDelete為T(mén)RUE,則調用“C”運算符號delete銷(xiāo)毀MFC線(xiàn)程對象自身(delete this),這將導致線(xiàn)程對象的析構函數被調用。若析構函數檢測線(xiàn)程句柄非空則調用CloseHandle關(guān)閉它。

        通常,讓m_bDelete為T(mén)RUE以便自動(dòng)地銷(xiāo)毀線(xiàn)程對象,釋放內存空間(MFC內存對象在堆中分配)。但是,有時(shí)候,在線(xiàn)程結束之后(Win32線(xiàn)程已經(jīng)不存在)保留MFC線(xiàn)程對象是有用的,當然程序員自己最后要記得銷(xiāo)毀該線(xiàn)程對象。

      3. 實(shí)現線(xiàn)程的消息循環(huán)

         

在MFC中,消息循環(huán)是由線(xiàn)程完成的。一般地,可以使用MFC缺省的消息循環(huán)(即使用函數CWindThrad::Run),但是,有些時(shí)候需要程序員自己實(shí)現一個(gè)線(xiàn)程的消息循環(huán),比如在用戶(hù)界面線(xiàn)程進(jìn)行一個(gè)長(cháng)時(shí)間計算處理或者等待另一個(gè)線(xiàn)程時(shí)。一般有如下形式:

while ( bDoingBackgroundProcessing)

{

MSG msg;

while ( ::PeekMessage( &msg, NULL,0, 0, PM_NOREMOVE ) )

{

if ( !PumpMessage( ) )

{

bDoingBackgroundProcessing = FALSE;

::PostQuitMessage( );

break;

}

}

// let MFC do its idle processing

LONG lIdle = 0;

while ( AfxGetApp()->OnIdle(lIdle++ ) );

// Perform some background processing here

// using another call to OnIdle

}

該段代碼的解釋參見(jiàn)圖5-3對線(xiàn)程的Run函數的圖解。

程序員實(shí)現線(xiàn)程的消息循環(huán)有兩個(gè)好處,一是顧及了MFC的Idle處理機制;二是在長(cháng)時(shí)間的處理中可以響應用戶(hù)產(chǎn)生的事件或者消息。

在同步對象上等待其他線(xiàn)程時(shí),也可以使用同樣的方式,只要把條件

bDoingBackgroundProcessing

換成如下形式:

WaitForSingObject(hHandleOfEvent,0) == WAIT_TIMEOUT

即可。

MFC處理線(xiàn)程和進(jìn)程時(shí)還引入了一個(gè)重要的概念:狀態(tài),如線(xiàn)程狀態(tài)(Thread State)、進(jìn)程狀態(tài)(Process State)、模塊狀態(tài)(Module State)等。由于這個(gè)概念在MFC中占有重要地位,涉及的內容比較多,所以專(zhuān)門(mén)在下一章來(lái)講述它。


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
MFC線(xiàn)程(一):簡(jiǎn)單介紹
淺議Visual C++多線(xiàn)程設計
多線(xiàn)程技術(shù)在VC++串口通信程序中的應用研究
多線(xiàn)程在C、Win32和MFC下的使用方法(轉)
Windows多線(xiàn)程多任務(wù)設計初步
多線(xiàn)程與串行通信
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久