国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
第八章 MFC的進程和線程
  1. MFC的進程和線程

     

    1. Win32的進程和線程概念

       

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

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

之所以有線程這個概念,是因為以線程而不是進程為調度對象效率更高:

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

     

  • 一個進程的所有線程共享進程的地址空間和全局變量,所以簡化了線程之間的通訊。

     

    1. Win32的進程處理簡介

       

      因為MFC沒有提供類處理進程,所以直接使用了Win32 API函數(shù)。

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

         

        調用CreateProcess函數(shù)創(chuàng)建新的進程,運行指定的程序。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描述進程的安全性屬性,NT下有用。

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

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

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

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

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

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

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

        lpProcessInformation指向PROCESS_INFORMATION結構,用來存儲返回的進程信息。

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

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

        typedef struct _PROCESS_INFORMATION {

        HANDLE hProcess;

        HANDLE hThread;

        DWORD dwProcessId;

        DWORD dwThreadId;

        }PROCESS_INFORMATION;

        進程信息結構包括進程句柄,主線程句柄,進程ID,主線程ID。

      2. 進程的終止

         

進程在以下情況下終止:

  • 調用ExitProcess結束進程;

     

  • 進程的主線程返回,隱含地調用ExitProcess導致進程結束;

     

  • 進程的最后一個線程終止;

     

  • 調用TerminateProcess終止進程。

     

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

     

    1. Win32的線程

       

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

         

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

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes,

DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress,

LPVOID lpParameter,

DWORD dwCreationFlags, // creation flags

LPDWORD lpThreadId

);

其中:

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

dwStackSize指定線程棧的尺寸,如果為0則與進程主線程棧相同。

lpStartAddress指定線程開始運行的地址。

lpParameter表示傳遞給線程的32位的參數(shù)。

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

lpThreadId用來存放返回的線程ID。

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

     

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

Normal級的線程可以被除了Idle級以外的任意線程搶占。

      1. 線程的終止

         

以下情況終止一個線程:

  • 調用了ExitThread函數(shù);

     

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

     

  • 調用ExitProcess導致進程的所有線程終止;

     

  • 調用TerminateThread終止一個線程;

     

  • 調用TerminateProcess終止一個進程時,導致其所有線程的終止。

     

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

      1. 線程局部存儲

         

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

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

TLS函數(shù)如下:

  • DWORD TlsAlloc()

     

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

  • BOOL TlsSetValue(

     

DWORD dwTlsIndex, //TLS index to set value for

LPVOID lpTlsValue //value to be stored

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

lpTlsValue是線程在TLS槽中存放的數(shù)據(jù)指針,指針指向線程要保存的數(shù)據(jù)。

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

  • LPVOID TlsGetValue(

     

DWORD dwTlsIndex // TLS index to retrieve value for

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

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

  • BOOL TlsFree(

     

DWORD dwTlsIndex // TLS index to free

);

其中:

dwTlsIndex是TlsAlloc分配的索引。

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

    1. 線程同步

       

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

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

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

      1. 同步對象

         

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

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

  1. 關鍵段對象:

     

    首先,定義一個關鍵段對象cs:

    CRITICAL_SECTION cs;

    然后,初始化該對象。初始化時把對象設置為NOT_SINGALED,表示允許線程使用資源:

    InitializeCriticalSection(&cs);

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

    完成關鍵段的執(zhí)行之后,調用LeaveCriticalSection函數(shù),其他的線程就可以繼續(xù)執(zhí)行該段代碼。如果該函數(shù)不被調用,則其他線程將無限期的等待。

  2. 事件對象

     

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

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

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

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

  3. 互斥對象

     

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

    互斥對象可以在進程間使用,但關鍵段對象只能用于同一進程的線程之間。

  4. 信號量對象

     

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

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

  5. 此外,還有其他句柄可以用來同步線程:

     

文件句柄(FILE HANDLES)

命名管道句柄(NAMED PIPE HANDELS)

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

通訊設備句柄(COMMUNICTION DEVICE HANDLES)

進程句柄(PROCESS HANDLES)

線程句柄(THREAD HANDLES)

例如,當一個進程或線程結束時,進程或線程句柄獲得信號,等待該進程或者線程結束的線程被釋放。

      1. 等待函數(shù)

         

Win32提供了一組等待函數(shù)用來讓一個線程阻塞自己的執(zhí)行。等待函數(shù)分三類:

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

     

    這類函數(shù)包括:

    SignalObjectAndWait

    WaitForSingleObject

    WaitForSingleObjectEx

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

    在以下情況下等待函數(shù)返回:

    同步對象獲得信號時返回;

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

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

     

    這類函數(shù)包括:

    WaitForMultipleObjects

    WaitForMultipleObjectsEx

    MsgWaitForMultipleObjects

    MsgWaitForMultipleObjectsEx

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

    在以下情況下等待函數(shù)返回:

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

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

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

     

這類函數(shù)包括:

MsgWaitForMultipleObjectsEx

SignalObjectAndWait

WaitForMultipleObjectsEx

WaitForSingleObjectEx

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

    1. MFC的線程處理

       

      在Win32 API的基礎之上,MFC提供了處理線程的類和函數(shù)。處理線程的類是CWinThread,函數(shù)是AfxBeginThread、AfxEndThread等。

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

      CWinThread是MFC線程類,它的成員變量m_hThread和m_hThreadID是對應的Win32線程句柄和線程ID。

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

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

      1. 創(chuàng)建用戶界面線程

         

通過以下步驟創(chuàng)建一個用戶界面線程:

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

     

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

     

  • 使用AfxBeginThread創(chuàng)建MFC線程對象和Win32線程對象。如果創(chuàng)建線程時沒有指定CREATE_SUSPENDED,則開始執(zhí)行線程。

     

  • 如果創(chuàng)建線程是指定了CREATE_SUSPENDED,則在適當?shù)牡胤秸{用函數(shù)ResumeThread開始執(zhí)行線程。

     

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

         

        程序員不必從CWinThread派生新的線程類,只需要提供一個控制函數(shù),由線程啟動后執(zhí)行該函數(shù)。

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

        如果創(chuàng)建線程是指定了CREATE_SUSPENDED,則在適當?shù)牡胤秸{用函數(shù)ResumeThread開始執(zhí)行線程。

        雖然程序員沒有從CWinThread派生類,但是MFC給工作者線程提供了缺省的CWinThread對象。

      2. AfxBeginThread

         

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

  1. 用戶界面線程的AfxBeginThread

     

    用戶界面線程的AfxBeginThread的原型如下:

    CWinThread* AFXAPI AfxBeginThread(

    CRuntimeClass* pThreadClass,

    int nPriority,

    UINT nStackSize,

    DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs)

    其中:

    參數(shù)1是從CWinThread派生的RUNTIME_CLASS類;

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

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

    參數(shù)4是一個創(chuàng)建標識,如果是CREATE_SUSPENDED,則在懸掛狀態(tài)創(chuàng)建線程,在線程創(chuàng)建后線程掛起,否則線程在創(chuàng)建后開始線程的執(zhí)行。

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

  2. 工作者線程的AfxBeginThread

     

    工作者線程的AfxBeginThread的原型如下:

    CWinThread* AFXAPI AfxBeginThread(

    AFX_THREADPROC pfnThreadProc,

    LPVOID pParam,

    int nPriority,

    UINT nStackSize,

    DWORD dwCreateFlags,

    LPSECURITY_ATTRIBUTES lpSecurityAttrs)

    其中:

    參數(shù)1指定控制函數(shù)的地址;

    參數(shù)2指定傳遞給控制函數(shù)的參數(shù);

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

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

     

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

      1. CreateThread和_AfxThreadEntry

         

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

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

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

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

        struct _AFX_THREAD_STARTUP

        {

        //傳遞給線程啟動的參數(shù)(IN)

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

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

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

        _PNH pfnNewHandler; //新線程的句柄

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

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

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

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

        };

        該結構作為線程開始函數(shù)的參數(shù)被傳遞給_beginthreadex函數(shù)來創(chuàng)建和啟動線程。_beginthreadex函數(shù)是“C”的線程創(chuàng)建函數(shù),具有如下原型:

        unsigned long _beginthreadex(

        void *security,

        unsigned stack_size,

        unsigned ( __stdcall *start_address )( void * ),

        void *arglist,

        unsigned initflag,

        unsigned *thrdaddr );

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

         

         

      2. 線程的結束

         

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

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

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

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

         

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

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

}

該段代碼的解釋參見圖5-3對線程的Run函數(shù)的圖解。

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

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

bDoingBackgroundProcessing

換成如下形式:

WaitForSingObject(hHandleOfEvent,0) == WAIT_TIMEOUT

即可。

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


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

聯(lián)系客服