• <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>

            twzheng's cppblog

            『站在風(fēng)口浪尖緊握住鼠標(biāo)旋轉(zhuǎn)!』 http://www.cnblogs.com/twzheng

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              136 隨筆 :: 78 文章 :: 353 評(píng)論 :: 0 Trackbacks
            AfxBeginThread函數(shù)初探
            版權(quán)所有 codesky.net 2003-2005
            發(fā)表時(shí)間:2005-1-16    關(guān)鍵字:不詳

            在進(jìn)行多線程程序設(shè)計(jì)的時(shí)候,我們經(jīng)常用到AfxBeginThread函數(shù)來啟動(dòng)一條線程
            該函數(shù)使用起來非常的簡單方便,其定義如下

            CWinThread* AfxBeginThread(
               AFX_THREADPROC pfnThreadProc,//線程函數(shù)地址
               LPVOID pParam,//線程參數(shù)
               int nPriority = THREAD_PRIORITY_NORMAL,//線程優(yōu)先級(jí)
               UINT nStackSize = 0,//線程堆棧大小,默認(rèn)為1M
               DWORD dwCreateFlags = 0,//
               LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
            );

            CWinThread* AfxBeginThread(
               CRuntimeClass* pThreadClass,
               int nPriority = THREAD_PRIORITY_NORMAL,
               UINT nStackSize = 0,
               DWORD dwCreateFlags = 0,
               LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
            );

            參數(shù)說明:
            pfnThreadProc:線程函數(shù)的地址,該參數(shù)不能設(shè)置為NULL,線程函數(shù)必須定義成全局函數(shù)或者類的靜態(tài)成員函數(shù)
            例如:
            UINT myThreadFunc(LPVOID lparam)
            或者
            class A
            {
            public:
                    static UINT __stdcall myThreadFunc(LPVOID lparam);
            }
            之所以要定義成類的靜態(tài)成員函數(shù),是因?yàn)轭惖撵o態(tài)成員函數(shù)不屬于某個(gè)類對(duì)象,這樣在調(diào)用函數(shù)
            的時(shí)候就不用傳遞一個(gè)額外的this指針.

            pThreadClass:指向從CWinThread派生的子類對(duì)象的RUNTIME_CLASS

            pParam:要傳遞給線程函數(shù)的參數(shù)

            nPriority:要啟動(dòng)的線程的優(yōu)先級(jí),默認(rèn)優(yōu)先級(jí)為THREAD_PRIORITY_NORMAL(普通優(yōu)先級(jí)),關(guān)于線程
             優(yōu)先級(jí)的詳細(xì)說明請(qǐng)參考Platform SDK SetThreadPriority函數(shù)說明

            nStackSize:新線程的堆棧大小,如果設(shè)置為0,則使用默認(rèn)大小,在應(yīng)用程序中一般情況下線程的默認(rèn)堆棧大小
             為1M

            dwCreateFlags:線程創(chuàng)建標(biāo)志,該參數(shù)可以指定為下列標(biāo)志
             CREATE_SUSPENDED:以掛起方式啟動(dòng)線程,如果你在線程啟動(dòng)之前想初始化一些CWinThread類中的一些成員變量
             比如:m_bAutoDelete或者你的派生類中的成員變量,當(dāng)初始化完成之后,你可以使用CWinThread類的ResumeThread
             成員函數(shù)來恢復(fù)線程的運(yùn)行
             如果把該標(biāo)志設(shè)置為0,則表示立即啟動(dòng)線程
            lpSecurityAttrs:指向安全描述符的指針,如果使用默認(rèn)的安全級(jí)別只要講該參數(shù)設(shè)置為NULL就可以了!

            上面就是AfxBeginThread函數(shù)的簡單說明,我們在使用的時(shí)候一般情況下只要指定前兩個(gè)參數(shù),其他
            參數(shù)使用默認(rèn)值就可以.嗯,的確,使用起來是很簡單,只要這個(gè)函數(shù)一被調(diào)用,就創(chuàng)建了一個(gè)線程.
            但是大家有沒有想過,AfxBeginThread函數(shù)究竟是如何啟動(dòng)的線程呢?它的內(nèi)部是如何實(shí)現(xiàn)的呢?

            下面我們就來看一下AfxBeginThread函數(shù)的內(nèi)部實(shí)現(xiàn)

            //啟動(dòng)worker線程
            CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
             int nPriority, UINT nStackSize, DWORD dwCreateFlags,
             LPSECURITY_ATTRIBUTES lpSecurityAttrs)
            {
            #ifndef _MT
                     pfnThreadProc;
                     pParam;
                     nPriority;
                     nStackSize;
                     dwCreateFlags;
                     lpSecurityAttrs;

                     return NULL;
            #else
                     ASSERT(pfnThreadProc != NULL);

                     CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
                     ASSERT_VALID(pThread);

                     if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
                              lpSecurityAttrs))
                     {
                              pThread->Delete();
                              return NULL;
                     }
                     VERIFY(pThread->SetThreadPriority(nPriority));
                     if (!(dwCreateFlags & CREATE_SUSPENDED))
                              VERIFY(pThread->ResumeThread() != (DWORD)-1);

                     return pThread;
            #endif //!_MT)
            }

            //啟動(dòng)UI線程
            CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,
             int nPriority, UINT nStackSize, DWORD dwCreateFlags,
             LPSECURITY_ATTRIBUTES lpSecurityAttrs)
            {
            #ifndef _MT
                    pThreadClass;
                    nPriority;
                    nStackSize;
                    dwCreateFlags;
                    lpSecurityAttrs;

                    return NULL;
            #else
                    ASSERT(pThreadClass != NULL);
                    ASSERT(pThreadClass->IsDerivedFrom(RUNTIME_CLASS(CWinThread)));

                    CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();
                    if (pThread == NULL)
                            AfxThrowMemoryException();
                    ASSERT_VALID(pThread);

                    pThread->m_pThreadParams = NULL;
                    if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
                            lpSecurityAttrs))
                    {
                            pThread->Delete();
                            return NULL;
                    }
                    VERIFY(pThread->SetThreadPriority(nPriority));
                    if (!(dwCreateFlags & CREATE_SUSPENDED))
                            VERIFY(pThread->ResumeThread() != (DWORD)-1);

                    return pThread;
            #endif //!_MT
            }

            從上面的代碼中可以看出AfxBeginThread所做的事情主要有以下幾點(diǎn):

            1.在heap中配置一個(gè)新的CWinThread對(duì)象(worker線程)
            代碼如:CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
            調(diào)用CRuntimeClass結(jié)構(gòu)中的CreateObject函數(shù)創(chuàng)建CWinThread對(duì)象
            CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();
            CRuntimeClass以及MFC相關(guān)類的內(nèi)部實(shí)現(xiàn),詳情請(qǐng)參考
            《深入淺出MFC》侯捷著

            2.調(diào)用CWinThread::CreateThread()并設(shè)定屬性,使線程以掛起狀態(tài)產(chǎn)生
            pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,lpSecurityAttrs);

            3.設(shè)定線程的優(yōu)先權(quán)
            pThread->SetThreadPriority(nPriority);

            4.調(diào)用CWinThread::ResumeThread
            pThread->ResumeThread();

            通過上面的說明,我想大家對(duì)該函數(shù)到底在內(nèi)部都做了什么,應(yīng)該有一個(gè)初步的了解了!
            對(duì)于VC老手來說,這篇文章可能并沒有什么可讀之處,但是對(duì)于初學(xué)者來說,還是有一定的
            價(jià)值的!
            總之,希望這篇文章能給各位一點(diǎn)點(diǎn)的幫助!

            posted on 2007-05-05 13:42 譚文政 閱讀(668) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)編程
            久久国产成人午夜AV影院| 日本道色综合久久影院| 久久国产热这里只有精品| 国产精品无码久久久久| 亚洲国产成人精品91久久久| 亚洲国产成人久久综合区| 亚洲中文久久精品无码| 久久www免费人成看国产片| 精品熟女少妇AV免费久久| 国产欧美久久久精品| 久久久WWW成人| 国产精品久久久久影视不卡 | 四虎国产精品成人免费久久| 久久婷婷成人综合色综合| 9999国产精品欧美久久久久久| 久久久精品国产| 久久久无码精品午夜| 69久久夜色精品国产69| 婷婷久久综合| 精品久久久久久久久久久久久久久| 欧美国产成人久久精品| 久久99精品久久久久久噜噜| 久久亚洲精精品中文字幕| 亚洲性久久久影院| 久久久久国产一区二区| 99久久免费只有精品国产| 国产精品免费福利久久| 久久精品国产亚洲av麻豆色欲| 四虎亚洲国产成人久久精品| 国产成人99久久亚洲综合精品| 91久久精品91久久性色| 久久男人Av资源网站无码软件 | 久久国产精品-国产精品| 精品久久久噜噜噜久久久| 国产成人精品三上悠亚久久| 欧美性猛交xxxx免费看久久久| 精品国产91久久久久久久a| 欧美亚洲国产精品久久蜜芽| 日本三级久久网| 99久久夜色精品国产网站| 国产精品免费久久久久久久久|