CreateThread()、_beginthread()以及_beginthreadex()聯絡與區別

licup123發表於2009-08-13

聯絡:

CreateThread、_beginthread和_beginthreadex都是用來啟動執行緒的。

區別:

_beginthread是_beginthreadex的功能子集,_beginthreadex是微軟的C/C++執行時庫函式,CreateThread是作業系統的函式。雖然_beginthread內部是呼叫_beginthreadex但他遮蔽了象安全特性這樣的功能,所以_beginthread與CreateThread不是同等級別,_beginthreadex和CreateThread在功能上完全可替代,我們就來比較一下_beginthreadex與CreateThread!  

<>中有很詳細地介紹:

注意:若要建立一個新執行緒,絕對不要使用CreateThread,而應使用_beginthreadex.  
  Why?考慮標準C執行時庫的一些變數和函式,如errno,這是一個全域性變數。全域性變數用於  
  多執行緒會出什麼事,你一定知道的了。故必須存在一種機制,使得每個執行緒能夠引用它自己的  
  errno變數,又不觸及另一執行緒的errno變數._beginthreadex就為每個執行緒分配自己的  
  tiddata記憶體結構。該結構儲存了許多像errno這樣的變數和函式的值、地址(自己看去吧)。  
  通過執行緒區域性儲存將tiddata與執行緒聯絡起來。具體實現在Threadex.c中有。  
  結束執行緒使用函式_endthreadex函式,釋放掉執行緒的tiddata資料塊。  
  CRT的函式庫線上程出現之前就已經存在,所以原有的CRT不能真正支援執行緒,這導致我們在程式設計的時候有了CRT庫的選擇,在MSDN中查閱CRT的函式時都有:  
  Libraries  
  LIBC.LIB   Single   thread   static   library,   retail   version    
  LIBCMT.LIB   Multithread   static   library,   retail   version    
  MSVCRT.LIB   Import   library   for   MSVCRT.DLL,   retail   version    
  這樣的提示!  
  對於執行緒的支援是後來的事!  
  這也導致了許多CRT的函式在多執行緒的情況下必須有特殊的支援,不能簡單的使用CreateThread就OK。  
  大多的CRT函式都可以在CreateThread執行緒中使用,看資料說只有signal()函式不可以,會導致程式終止!但可以用並不是說沒有問題!  
  有些CRT的函式象malloc(),   fopen(),   _open(),   strtok(),   ctime(),   或localtime()等函式需要專門的執行緒區域性儲存的資料塊,這個資料塊通常需要在建立執行緒的時候就建立,如果使用CreateThread,這個資料塊就沒有建立,然後會怎樣呢?在這樣的執行緒中還是可以使用這些函式而且沒有出錯,實際上函式發現這個資料塊的指標為空時,會自己建立一個,然後將其與執行緒聯絡在一起,這意味著如果你用CreateThread來建立執行緒,然後使用這樣的函式,會有一塊記憶體在不知不覺中建立,遺憾的是,這些函式並不將其刪除,而CreateThread和ExitThread也無法知道這件事,於是就會有Memory   Leak,線上程頻繁啟動的軟體中(比如某些伺服器軟體),遲早會讓系統的記憶體資源耗盡!  
  _beginthreadex(內部也呼叫CreateThread)和_endthreadex就對這個記憶體塊做了處理,所以沒有問題!(不會有人故意用CreateThread建立然後用_endthreadex終止吧,而且執行緒的終止最好不要顯式的呼叫終止函式,自然退出最好!)  
  談到Handle的問題,_beginthread的對應函式_endthread自動的呼叫了CloseHandle,而_beginthreadex的對應函式_endthreadex則沒有,所以CloseHandle無論如何都是要呼叫的不過_endthread可以幫你執行自己不必寫,其他兩種就需要自己寫!(Jeffrey   Richter強烈推薦儘量不用顯式的終止函式,用自然退出的方式,自然退出當然就一定要自己寫CloseHandle) 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10697500/viewspace-612085/,如需轉載,請註明出處,否則將追究法律責任。

相關文章