CreateThread, AfxBeginThread,_beginthread, _beginthreadex

來源:互聯網
上載者:User

CreateThread, AfxBeginThread,_beginthread, _beginthreadex的區別時間:2009-09-29 22:42:23來源:網路 作者:未知 點擊:546次 CreateThread是Windows的API函數(SDK函數的標準形式,直截了當的建立方式,任何場合都可以使用),提供作業系統層級的建立線程的操作,且僅限於工作者線程。不調用MFC和RTL的函數時,可以用CreateThread,其它情況不要輕易。在使 CreateThread是Windows的API函數(SDK函數的標準形式,直截了當的建立方式,任何場合都可以使用),提供作業系統層級的建立線程的操作,且僅限於工作者線程。不調用MFC和RTL的函數時,可以用CreateThread,其它情況不要輕易。在使用的過程中要考慮到進程的同步與互斥的關係(防止死結)。線程函數定義為:DWORD WINAPI _yourThreadFun(LPVOID pParameter)。但它沒有考慮:(1)C Runtime中需要對多線程進行紀錄和初始化,以保證C函數庫工作正常(典型的例子是strtok函數)。(2)MFC也需要知道新線程的建立,也需要做一些初始化工作(當然,如果沒用MFC就沒事了)。 AfxBeginThread:MFC中線程建立的MFC函數,首先建立了相應的CWinThread對象,然後調用CWinThread::CreateThread, 在CWinThread::CreateThread中,完成了對線程對象的初始化工作,然後,調用_beginthreadex(AfxBeginThread相比較更為安全)建立線程。它簡化了操作或讓線程能夠響應訊息,即可用於介面線程,也可以用於工作者線程,但要注意不要在一個MFC程式中使用_beginthreadex()或CreateThread()。線程函數定義為:UINT _yourThreadFun(LPVOID pParam) _beginthreadex:MS對C Runtime庫的擴充SDK函數,首先針對C Runtime庫做了一些初始化的工作,以保證C Runtime庫工作正常。然後,調用CreateThread真正建立線程。 僅使用Runtime Library時,可以用_BegingThread。 uintptr_t _beginthread( void( *start_address )( void * ), unsigned stack_size, void *arglist ); uintptr_t _beginthreadex( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); _beginthreadex( NULL, 0, threadProc, &pagram, 0, (unsigned int *) idThread ); 小節:實際上,這三個函數之間存在一定的調用關係,第一個純粹一些,後兩個完成自己相應的工作之後,調用前者實現線程的建立。其中CreateThread是由作業系統提供的介面,而AfxBeginThread和_BeginThread則是編譯器對它的封裝。 小節:用_beginthreadex()、_endthreadex函數應該是最佳選擇,且都是C Run-time Library中的函數,函數的參數和資料類型都是C Run-time Library中的類型,這樣在啟動線程時就不需要進行Windows資料類型和C Run-time Library中的資料類型之間的轉化,從而,減低了線程啟動時的資源消耗和時間的消耗。但使用_beginthread,無法建立帶有安全屬性的新線程,無法建立暫停線程,也無法獲得 線程ID,_endthread的情況類似,它不帶參數,這意味這線程的結束代碼必須寫入程式碼為0。 小節:MFC也是C++類庫(只不過是Microsoft的C++類庫,不是標準的C++類庫),在MFC中也封裝了new和delete兩中運算子,所以用到new和delete的地方不一定非要使用_beginthreadex() 函數,用其他兩個函數都可以。 _beginthreadex和_beginthread在回調入口函數之前進行一些線程相關的CRT的初始化操作。 CRT的函數庫線上程出現之前就已經存在,所以原有的CRT不能真正支援線程,這也導致了許多CRT的函數在多線程的情況下必須有特殊的支援,不能簡單的使用CreateThread就OK。 轉載自: http://www.cppblog.com/bidepan2023/archive/2007/10/31/35627.html 當你打算實現一個多線程(非MFC)程式,你會選擇一個單線程的CRT(C執行階段程式庫)嗎?如果你的回答是NO, 那麼會帶來另外一個問題,你選擇了CreateThread來建立一個線程嗎? 大多數人也許會立刻回答YES。可是很不幸,這是錯誤的選擇。我先來說一下我的結論,待會告訴你為什麼。 如果要作多線程(非MFC)程式,在主線程以外的任何線程內 - 使用malloc(),free(),new - 調用stdio.h或io.h,包括fopen(),open(),getchar(),write(),printf(),errno - 使用浮點變數和浮點運算函數 - 調用那些使用靜態緩衝區的函數如: asctime(),strtok(),rand()等。你就應該使用多線程的CRT並配合_beginthreadex(該函數只存在於多線程CRT), 其他情況下你可以使用單線程的CRT並配合CreateThread。 因為對產生的線程而言,_beginthreadex比之CreateThread會為上述操作多做額外的簿記工作,比如協助strtok()為每個線程準備一份緩衝區。然而多線程程式極少情況不使用上述那些函數(比如記憶體配置或者io),所以與其每次都要思考是要使用_beginthreadex還是CreateThread,不如就一棍子敲定_beginthreadex。 當然你也許會藉助win32來處理記憶體配置和Io,這時候你確實可以以單線程crt配合CreateThread,因為io的重任已經從crt轉交給了win32。這時通常你應該使用HeapAlloc,HeapFree來處理記憶體配置,用CreateFile或者GetStdHandle來處理Io。 還有一點比較重要的是_beginthreadex傳回的雖然是個unsigned long,其實是個線程Handle(事實上_beginthreadex在內部就是調用了CreateThread),所以你應該用CloseHandle來結束他。千萬不要使用ExitThread()來退出_beginthreadex建立的線程,那樣會喪失釋放簿記資料的機會,應該使用_endthreadex. 本篇文章來源於:開發學院 http://edu.codepub.com 原文連結:http://edu.codepub.com/2009/0929/15934.php

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.