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

            『站在風口浪尖緊握住鼠標旋轉!』 http://www.cnblogs.com/twzheng

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              136 隨筆 :: 78 文章 :: 353 評論 :: 0 Trackbacks
            AfxBeginThread函數初探
            版權所有 codesky.net 2003-2005
            發表時間:2005-1-16    關鍵字:不詳

            在進行多線程程序設計的時候,我們經常用到AfxBeginThread函數來啟動一條線程
            該函數使用起來非常的簡單方便,其定義如下

            CWinThread* AfxBeginThread(
               AFX_THREADPROC pfnThreadProc,//線程函數地址
               LPVOID pParam,//線程參數
               int nPriority = THREAD_PRIORITY_NORMAL,//線程優先級
               UINT nStackSize = 0,//線程堆棧大小,默認為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
            );

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

            pThreadClass:指向從CWinThread派生的子類對象的RUNTIME_CLASS

            pParam:要傳遞給線程函數的參數

            nPriority:要啟動的線程的優先級,默認優先級為THREAD_PRIORITY_NORMAL(普通優先級),關于線程
             優先級的詳細說明請參考Platform SDK SetThreadPriority函數說明

            nStackSize:新線程的堆棧大小,如果設置為0,則使用默認大小,在應用程序中一般情況下線程的默認堆棧大小
             為1M

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

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

            下面我們就來看一下AfxBeginThread函數的內部實現

            //啟動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)
            }

            //啟動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所做的事情主要有以下幾點:

            1.在heap中配置一個新的CWinThread對象(worker線程)
            代碼如:CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
            調用CRuntimeClass結構中的CreateObject函數創建CWinThread對象
            CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();
            CRuntimeClass以及MFC相關類的內部實現,詳情請參考
            《深入淺出MFC》侯捷著

            2.調用CWinThread::CreateThread()并設定屬性,使線程以掛起狀態產生
            pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,lpSecurityAttrs);

            3.設定線程的優先權
            pThread->SetThreadPriority(nPriority);

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

            通過上面的說明,我想大家對該函數到底在內部都做了什么,應該有一個初步的了解了!
            對于VC老手來說,這篇文章可能并沒有什么可讀之處,但是對于初學者來說,還是有一定的
            價值的!
            總之,希望這篇文章能給各位一點點的幫助!

            posted on 2007-05-05 13:42 譚文政 閱讀(661) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程
            中文字幕久久久久人妻| 国产精品久久精品| 亚洲日韩欧美一区久久久久我| 久久久中文字幕日本| 亚洲AV无码久久精品成人| 久久青青草原精品国产| 久久播电影网| 三上悠亚久久精品| 久久综合给合综合久久| www.久久热.com| 亚洲狠狠婷婷综合久久久久| 欧美激情精品久久久久| 午夜欧美精品久久久久久久| 日本久久久久久中文字幕| 国内精品人妻无码久久久影院导航| 久久久久夜夜夜精品国产| 久久99精品久久久大学生| 久久精品无码一区二区三区免费 | 久久中文字幕精品| 久久精品国产99国产精偷| 久久久久免费精品国产| 色婷婷狠狠久久综合五月| 久久精品www| 国产99久久精品一区二区| 久久天天躁狠狠躁夜夜avapp| 久久久久久久综合日本亚洲| 久久精品国产亚洲αv忘忧草| 国产精品欧美亚洲韩国日本久久| 久久久无码精品亚洲日韩按摩| 一级女性全黄久久生活片免费 | 一级做a爰片久久毛片16| 久久精品国产亚洲精品2020| 欧美日韩精品久久免费| 欧美亚洲国产精品久久| 青青草原综合久久大伊人| 亚洲色欲久久久久综合网 | 狠狠色丁香久久婷婷综合| 女人高潮久久久叫人喷水| 久久人人爽人人爽人人片AV不| 久久国产AVJUST麻豆| 久久91精品国产91久|