• <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 | 国产精品欧美久久久久无广告 | 久久精品一区二区| 99久久久久| 久久精品国产亚洲AV影院| 国内精品久久久人妻中文字幕| 久久精品成人欧美大片| 亚洲国产一成人久久精品| 久久这里只有精品首页| 久久天天躁狠狠躁夜夜2020一| 亚洲精品高清国产一久久| 亚洲国产一成久久精品国产成人综合 | 色综合久久无码中文字幕| 久久久精品一区二区三区| 国产精品一区二区久久精品无码 | 欧洲成人午夜精品无码区久久| 爱做久久久久久| 国产精品久久久久影院嫩草| 亚洲精品无码久久不卡| 久久精品国产91久久麻豆自制 | 丰满少妇人妻久久久久久4| 亚洲精品无码久久千人斩| 久久婷婷人人澡人人| 老司机国内精品久久久久| 亚洲AV日韩精品久久久久久| 欧美激情精品久久久久久| 国产三级观看久久| 国内精品久久久久影院免费| 欧洲精品久久久av无码电影| 99久久免费国产精品特黄| 国产一区二区精品久久岳 | 四虎国产精品成人免费久久| 久久久久99精品成人片| 超级碰久久免费公开视频| 欧美亚洲国产精品久久蜜芽| 久久99久久99精品免视看动漫| 亚洲国产精品一区二区久久hs| 亚洲精品乱码久久久久久久久久久久 | 久久狠狠一本精品综合网| 国产亚洲美女精品久久久久狼| 久久久久久精品免费看SSS|