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

yehao's Blog

多線程編程之二——MFC中的多線程開發(fā)

五、MFC對多線程編程的支持

  MFC中有兩類線程,分別稱之為工作者線程和用戶界面線程。二者的主要區(qū)別在于工作者線程沒有消息循環(huán),而用戶界面線程有自己的消息隊列和消息循環(huán)。
  工作者線程沒有消息機(jī)制,通常用來執(zhí)行后臺計算和維護(hù)任務(wù),如冗長的計算過程,打印機(jī)的后臺打印等。用戶界面線程一般用于處理獨立于其他線程執(zhí)行之外的用戶輸入,響應(yīng)用戶及系統(tǒng)所產(chǎn)生的事件和消息等。但對于Win32的API編程而言,這兩種線程是沒有區(qū)別的,它們都只需線程的啟動地址即可啟動線程來執(zhí)行任務(wù)。
  在MFC中,一般用全局函數(shù)AfxBeginThread()來創(chuàng)建并初始化一個線程的運行,該函數(shù)有兩種重載形式,分別用于創(chuàng)建工作者線程和用戶界面線程。兩種重載函數(shù)原型和參數(shù)分別說明如下:

(1) CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
PfnThreadProc:指向工作者線程的執(zhí)行函數(shù)的指針,線程函數(shù)原型必須聲明如下:
UINT ExecutingFunction(LPVOID pParam);
請注意,ExecutingFunction()應(yīng)返回一個UINT類型的值,用以指明該函數(shù)結(jié)束的原因。一般情況下,返回0表明執(zhí)行成功。
  • pParam:傳遞給線程函數(shù)的一個32位參數(shù),執(zhí)行函數(shù)將用某種方式解釋該值。它可以是數(shù)值,或是指向一個結(jié)構(gòu)的指針,甚至可以被忽略;
  • nPriority:線程的優(yōu)先級。如果為0,則線程與其父線程具有相同的優(yōu)先級;
  • nStackSize:線程為自己分配堆棧的大小,其單位為字節(jié)。如果nStackSize被設(shè)為0,則線程的堆棧被設(shè)置成與父線程堆棧相同大小;
  • dwCreateFlags:如果為0,則線程在創(chuàng)建后立刻開始執(zhí)行。如果為CREATE_SUSPEND,則線程在創(chuàng)建后立刻被掛起;
  • lpSecurityAttrs:線程的安全屬性指針,一般為NULL;
 (2) CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,
int nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

 

  pThreadClass 是指向 CWinThread 的一個導(dǎo)出類的運行時類對象的指針,該導(dǎo)出類定義了被創(chuàng)建的用戶界面線程的啟動、退出等;其它參數(shù)的意義同形式1。使用函數(shù)的這個原型生成的線程也有消息機(jī)制,在以后的例子中我們將發(fā)現(xiàn)同主線程的機(jī)制幾乎一樣。

下面我們對CWinThread類的數(shù)據(jù)成員及常用函數(shù)進(jìn)行簡要說明。

  • m_hThread:當(dāng)前線程的句柄;
  • m_nThreadID:當(dāng)前線程的ID;
  • m_pMainWnd:指向應(yīng)用程序主窗口的指針
BOOL CWinThread::CreateThread(DWORD dwCreateFlags=0,
UINT nStackSize=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);

  該函數(shù)中的dwCreateFlags、nStackSize、lpSecurityAttrs參數(shù)和API函數(shù)CreateThread中的對應(yīng)參數(shù)有相同含義,該函數(shù)執(zhí)行成功,返回非0值,否則返回0。
  一般情況下,調(diào)用AfxBeginThread()來一次性地創(chuàng)建并啟動一個線程,但是也可以通過兩步法來創(chuàng)建線程:首先創(chuàng)建CWinThread類的一個對象,然后調(diào)用該對象的成員函數(shù)CreateThread()來啟動該線程。

virtual BOOL CWinThread::InitInstance();
  重載該函數(shù)以控制用戶界面線程實例的初始化。初始化成功則返回非0值,否則返回0。用戶界面線程經(jīng)常重載該函數(shù),工作者線程一般不使用InitInstance()。
virtual int CWinThread::ExitInstance();
  在線程終結(jié)前重載該函數(shù)進(jìn)行一些必要的清理工作。該函數(shù)返回線程的退出碼,0表示執(zhí)行成功,非0值用來標(biāo)識各種錯誤。同InitInstance()成員函數(shù)一樣,該函數(shù)也只適用于用戶界面線程。

六、MFC多線程編程實例

  在Visual C++ 6.0編程環(huán)境中,我們既可以編寫C風(fēng)格的32位Win32應(yīng)用程序,也可以利用MFC類庫編寫C++風(fēng)格的應(yīng)用程序,二者各有其優(yōu)缺點。基于Win32的應(yīng)用程序執(zhí)行代碼小巧,運行效率高,但要求程序員編寫的代碼較多,且需要管理系統(tǒng)提供給程序的所有資源;而基于MFC類庫的應(yīng)用程序可以快速建立起應(yīng)用程序,類庫為程序員提供了大量的封裝類,而且Developer Studio為程序員提供了一些工具來管理用戶源程序,其缺點是類庫代碼很龐大。由于使用類庫所帶來的快速、簡捷和功能強(qiáng)大等優(yōu)越性,因此除非有特殊的需要,否則Visual C++推薦使用MFC類庫進(jìn)行程序開發(fā)。

我們知道,MFC中的線程分為兩種:用戶界面線程和工作者線程。我們將分別舉例說明。

用 MFC 類庫編程實現(xiàn)工作者線程

例程5 MultiThread5

為了與Win32 API對照,我們使用MFC 類庫編程實現(xiàn)例程3 MultiThread3。

  1. 建立一個基于對話框的工程MultiThread5,在對話框IDD_MULTITHREAD5_DIALOG中加入一個編輯框IDC_MILLISECOND,一個按鈕IDC_START,標(biāo)題為“開始” ,一個進(jìn)度條IDC_PROGRESS1;
  2. 打開ClassWizard,為編輯框IDC_MILLISECOND添加int型變量m_nMilliSecond,為進(jìn)度條IDC_PROGRESS1添加CProgressCtrl型變量m_ctrlProgress;
  3. 在MultiThread5Dlg.h文件中添加一個結(jié)構(gòu)的定義:
    struct threadInfo
        {
        UINT nMilliSecond;
        CProgressCtrl* pctrlProgress;
        };
        
    線程函數(shù)的聲明:
    UINT ThreadFunc(LPVOID lpParam); 

    注意,二者應(yīng)在類CMultiThread5Dlg的外部。

    在類CMultiThread5Dlg內(nèi)部添加protected型變量:

    CWinThread* pThread; 
  4. 在MultiThread5Dlg.cpp文件中進(jìn)行如下操作:定義公共變量:
    threadInfo Info; 

    雙擊按鈕IDC_START,添加相應(yīng)消息處理函數(shù):

    void CMultiThread5Dlg::OnStart()
        {
        // TODO: Add your control notification handler code here
        UpdateData(TRUE);
        Info.nMilliSecond=m_nMilliSecond;
        Info.pctrlProgress=&m_ctrlProgress;
        pThread=AfxBeginThread(ThreadFunc,
        &Info);
        }
        
    在函數(shù)BOOL CMultiThread3Dlg::OnInitDialog()中添加語句:
    {
        ……
        // TODO: Add extra initialization here
        m_ctrlProgress.SetRange(0,99);
        m_nMilliSecond=10;
        UpdateData(FALSE);
        return TRUE;  // return TRUE  unless you set the focus to a control
        }
        
    添加線程處理函數(shù):
    UINT ThreadFunc(LPVOID lpParam)
        {
        threadInfo* pInfo=(threadInfo*)lpParam;
        for(int i=0;i<100;i++)
        {
        int nTemp=pInfo->nMilliSecond;
        pInfo->pctrlProgress->SetPos(i);
        Sleep(nTemp);
        }
        return 0;
        }

用 MFC 類庫編程實現(xiàn)用戶界面線程

創(chuàng)建用戶界面線程的步驟:

  1. 使用ClassWizard創(chuàng)建類CWinThread的派生類(以CUIThread類為例)
    class CUIThread : public CWinThread
        {
        DECLARE_DYNCREATE(CUIThread)
        protected:
        CUIThread();           // protected constructor used by dynamic creation
        // Attributes
        public:
        // Operations
        public:
        // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CUIThread)
        public:
        virtual BOOL InitInstance();
        virtual int ExitInstance();
        //}}AFX_VIRTUAL
        // Implementation
        protected:
        virtual ~CUIThread();
        // Generated message map functions
        //{{AFX_MSG(CUIThread)
        // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
        };
        
  2. 重載函數(shù)InitInstance()和ExitInstance()。
    BOOL CUIThread::InitInstance()
        {
        CFrameWnd* wnd=new CFrameWnd;
        wnd->Create(NULL,"UI Thread Window");
        wnd->ShowWindow(SW_SHOW);
        wnd->UpdateWindow();
        m_pMainWnd=wnd;
        return TRUE;
        }
        
    創(chuàng)建新的用戶界面線程
    void CUIThreadDlg::OnButton1()
        {
        CUIThread* pThread=new CUIThread();
        pThread->CreateThread();
        }
        
    請注意以下兩點:

    A、在UIThreadDlg.cpp的開頭加入語句:
    #include "UIThread.h"
    B、把UIThread.h中類CUIThread()的構(gòu)造函數(shù)的特性由 protected 改為 public。

      用戶界面線程的執(zhí)行次序與應(yīng)用程序主線程相同,首先調(diào)用用戶界面線程類的InitInstance()函數(shù),如果返回TRUE,繼續(xù)調(diào)用線程的Run()函數(shù),該函數(shù)的作用是運行一個標(biāo)準(zhǔn)的消息循環(huán),并且當(dāng)收到WM_QUIT消息后中斷,在消息循環(huán)過程中,Run()函數(shù)檢測到線程空閑時(沒有消息),也將調(diào)用OnIdle()函數(shù),最后Run()函數(shù)返回,MFC調(diào)用ExitInstance()函數(shù)清理資源。
      你可以創(chuàng)建一個沒有界面而有消息循環(huán)的線程,例如:你可以從CWinThread派生一個新類,在InitInstance函數(shù)中完成某項任務(wù)并返回FALSE,這表示僅執(zhí)行InitInstance函數(shù)中的任務(wù)而不執(zhí)行消息循環(huán),你可以通過這種方法,完成一個工作者線程的功能。

例程6 MultiThread6

  1. 建立一個基于對話框的工程MultiThread6,在對話框IDD_MULTITHREAD6_DIALOG中加入一個按鈕IDC_UI_THREAD,標(biāo)題為“用戶界面線程”
  2. 右擊工程并選中“New Class…”為工程添加基類為CWinThread派生線程類CUIThread。
  3. 給工程添加新對話框IDD_UITHREADDLG,標(biāo)題為“線程對話框”。
  4. 為對話框IDD_UITHREADDLG創(chuàng)建一個基于CDialog的類CUIThreadDlg。使用ClassWizard為CUIThreadDlg類添加WM_LBUTTONDOWN消息的處理函數(shù)OnLButtonDown,如下:
    void CUIThreadDlg::OnLButtonDown(UINT nFlags, CPoint point)
        {
        AfxMessageBox("You Clicked The Left Button!");
        CDialog::OnLButtonDown(nFlags, point);
        }
  5. 在UIThread.h中添加
    #include "UIThreadDlg.h"
    并在CUIThread類中添加protected變量CUIThread m_dlg:
    class CUIThread : public CWinThread
        {
        DECLARE_DYNCREATE(CUIThread)
        protected:
        CUIThread();           // protected constructor used by dynamic creation
        // Attributes
        public:
        // Operations
        public:
        // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CUIThread)
        public:
        virtual BOOL InitInstance();
        virtual int ExitInstance();
        //}}AFX_VIRTUAL
        // Implementation
        protected:
        CUIThreadDlg m_dlg;
        virtual ~CUIThread();
        // Generated message map functions
        //{{AFX_MSG(CUIThread)
        // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
        };
        
  6. 分別重載InitInstance()函數(shù)和ExitInstance()函數(shù):
    BOOL CUIThread::InitInstance()
        {
        m_dlg.Create(IDD_UITHREADDLG);
        m_dlg.ShowWindow(SW_SHOW);
        m_pMainWnd=&m_dlg;
        return TRUE;
        }
        int CUIThread::ExitInstance()
        {
        m_dlg.DestroyWindow();
        return CWinThread::ExitInstance();
        }
        
  7. 雙擊按鈕IDC_UI_THREAD,添加消息響應(yīng)函數(shù):
    void CMultiThread6Dlg::OnUiThread()
        {
        CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread));
        }
        
    并在MultiThread6Dlg.cpp的開頭添加:
    #include "UIThread.h"
        

  好了,編譯并運行程序吧。每單擊一次“用戶界面線程”按鈕,都會彈出一個線程對話框,在任何一個線程對話框內(nèi)按下鼠標(biāo)左鍵,都會彈出一個消息框。

posted on 2011-04-25 15:33 厚積薄發(fā) 閱讀(296) 評論(0)  編輯 收藏 引用 所屬分類: Windows編程

導(dǎo)航

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

統(tǒng)計

常用鏈接

留言簿

隨筆分類

文章分類

文章檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            性色av一区二区三区红粉影视| 亚洲欧美日韩国产另类专区| 老司机午夜精品视频在线观看| 海角社区69精品视频| 久久国产88| 久久久久久**毛片大全| 在线观看不卡| 亚洲丰满在线| 欧美视频第二页| 欧美伊久线香蕉线新在线| 久久精品亚洲乱码伦伦中文 | 日韩亚洲成人av在线| 欧美日韩蜜桃| 欧美在线免费观看| 久久综合狠狠| 亚洲桃色在线一区| 午夜久久一区| 亚洲激情视频在线观看| 中日韩高清电影网| 在线电影国产精品| 亚洲人成绝费网站色www| 国产精品国产三级国产专区53 | 亚洲精品一二区| 国产精品综合av一区二区国产馆| 玖玖综合伊人| 欧美三区视频| 欧美国产日本在线| 国产精品人成在线观看免费 | 亚洲高清免费| 国产精品一区在线观看| 亚洲丰满在线| 黄色一区二区三区| 99av国产精品欲麻豆| 伊人久久综合| 午夜精品久久久久久久久| 亚洲美女黄网| 久久精品二区三区| 亚洲欧美成人一区二区三区| 久久人人97超碰精品888| 亚洲女同性videos| 欧美成人午夜激情| 久久精品日韩| 国产精品久久久久久久浪潮网站| 欧美激情按摩| 狠狠色狠狠色综合日日五| 亚洲与欧洲av电影| 亚洲一区二区在| 欧美精品一区在线发布| 欧美成人国产| 一区二区亚洲精品| 欧美诱惑福利视频| 欧美怡红院视频| 国产精品爱久久久久久久| 亚洲精品免费在线| 亚洲精品一区二区三区在线观看| 久久五月激情| 久久久另类综合| 国产一区二区三区视频在线观看 | 免费成人毛片| 曰韩精品一区二区| 久久久久九九九| 久久久美女艺术照精彩视频福利播放 | 日韩视频免费| 中文久久精品| 久久久av网站| 国产日韩av一区二区| 亚洲午夜精品福利| 99视频在线观看一区三区| 美女网站久久| 欧美激情一区二区三区在线| 亚洲激情一区| 欧美激情综合色| 亚洲人成网在线播放| 一本色道久久综合狠狠躁篇的优点 | 亚洲日本成人女熟在线观看| 日韩视频中文| 欧美日韩国产成人| 国产精品99久久99久久久二8 | 亚洲国产精品一区二区尤物区 | 在线一区二区视频| 亚洲综合另类| 国产小视频国产精品| 久久国产欧美日韩精品| 美女91精品| 99亚洲精品| 国产精品一区在线观看| 久久久精品一区| 亚洲国产日韩一区二区| 中国成人黄色视屏| 国产一级久久| 欧美激情一区二区在线 | 一区二区三区日韩欧美| 欧美在线短视频| 亚洲韩国一区二区三区| 欧美视频官网| 久久夜色精品亚洲噜噜国产mv| 亚洲黄色在线观看| 欧美一区日本一区韩国一区| 亚洲国产成人av| 国产精品久久久99| 久热综合在线亚洲精品| 在线一区二区三区四区| 久久综合影音| 亚洲欧美日韩综合一区| 亚洲第一成人在线| 国产精品午夜av在线| 免费日韩精品中文字幕视频在线| 亚洲深夜福利网站| 欧美电影免费| 欧美一级艳片视频免费观看| 亚洲人体一区| 激情久久影院| 国产精品麻豆va在线播放| 猛干欧美女孩| 久久国产精品色婷婷| 99精品国产高清一区二区| 麻豆视频一区二区| 欧美一区二区三区久久精品茉莉花| 亚洲第一页中文字幕| 国产精品爽爽爽| 欧美日韩一二三四五区| 美女视频黄免费的久久| 欧美在线亚洲在线| 亚洲专区国产精品| 在线综合+亚洲+欧美中文字幕| 欧美不卡视频一区发布| 久久久精品一品道一区| 午夜视频在线观看一区二区三区| 99精品视频免费观看| 亚洲国产成人久久综合| 国内精品视频在线观看| 国产日韩精品视频一区| 国产精品久久国产精麻豆99网站| 欧美激情影音先锋| 欧美精品久久久久久久免费观看| 久久婷婷激情| 美女任你摸久久| 久久一区二区三区四区| 久久久999| 久久蜜桃精品| 久久久久久自在自线| 久久久91精品| 久久婷婷丁香| 免费短视频成人日韩| 免费观看日韩| 欧美激情一二区| 欧美日韩人人澡狠狠躁视频| 欧美日韩免费观看一区三区 | 性欧美1819性猛交| 欧美一区二区三区视频在线观看 | 葵司免费一区二区三区四区五区| 久久久九九九九| 久久在线免费视频| 欧美成人r级一区二区三区| 欧美激情综合| 亚洲精品免费在线播放| 一级日韩一区在线观看| 亚洲一区综合| 香蕉乱码成人久久天堂爱免费| 午夜日韩av| 玖玖在线精品| 欧美伦理在线观看| 国产精品久久久久9999吃药| 国产精品免费网站| 好吊日精品视频| 亚洲欧洲免费视频| 亚洲婷婷免费| 久久天天躁狠狠躁夜夜av| 欧美黄色小视频| 一区二区高清| 久久精品国产亚洲一区二区| 牛牛影视久久网| 国产精品呻吟| 亚洲日韩欧美视频一区| 亚洲免费视频在线观看| 美女网站久久| 一区二区三区不卡视频在线观看| 欧美一级视频免费在线观看| 欧美电影在线免费观看网站| 国产精品国产三级欧美二区| 国产婷婷成人久久av免费高清| 亚洲黄色有码视频| 性欧美xxxx大乳国产app| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲人成人一区二区三区| 亚洲欧美精品在线| 欧美精品一区二区三区在线播放 | 久久综合一区二区| 欧美午夜宅男影院在线观看| 黄色在线成人| 午夜日韩av| 亚洲人成网站999久久久综合| 欧美一区二区三区男人的天堂| 欧美极品aⅴ影院| 韩国美女久久| 性色av一区二区怡红| 亚洲激情国产| 久久在线视频在线| 国产色综合久久| 亚洲综合色自拍一区|