日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CreateThread()与beginthread()的区别详细解析

發布時間:2025/3/12 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CreateThread()与beginthread()的区别详细解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
很多開發者不清楚這兩者之間的關系,他們隨意選一個函數來用,發現也沒有什么大問題,于是就忙于解決更為緊迫的任務去了。等到有一天忽然發現一個程序運行時間很長的時候會有細微的內存泄露,開發者絕對不會想到是因為這兩套函數用混的結果

我們知道在Windows下創建一個線程的方法有兩種,一種就是調用Windows API CreateThread()來創建線程;另外一種就是調用MSVC CRT的函數_beginthread()或_beginthreadex()來創建線程。相應的退出線程也有兩個函數Windows API的ExitThread()和CRT的_endthread()。這兩套函數都是用來創建和退出線程的,它們有什么區別呢?

很多開發者不清楚這兩者之間的關系,他們隨意選一個函數來用,發現也沒有什么大問題,于是就忙于解決更為緊迫的任務去了,而沒有對它們進行深究。等到有一天忽然發現一個程序運行時間很長的時候會有細微的內存泄露,開發者絕對不會想到是因為這兩套函數用混的結果。

根據Windows API和MSVC CRT的關系,可以看出來_beginthread()是對CreateThread()的包裝,它最終還是調用CreateThread()來創建線程。那么在_beginthread()調用CreateThread()之前做了什么呢?我們可以看一下_beginthread()的源代碼,它位于CRT源代碼中的thread.c。我們可以發現它在調用CreateThread()之前申請了一個叫_tiddata的結構,然后將這個結構用_initptd()函數初始化之后傳遞給_beginthread()自己的線程入口函數_threadstart。_threadstart首先把由_beginthread()傳過來的_tiddata結構指針保存到線程的顯式TLS數組,然后它調用用戶的線程入口真正開始線程。在用戶線程結束之后,_threadstart()函數調用_endthread()結束線程。并且_threadstart還用__try/__except將用戶線程入口函數包起來,用于捕獲所有未處理的信號,并且將這些信號交給CRT處理。

所以除了信號之外,很明顯CRT包裝Windows API線程接口的最主要目的就是那個_tiddata。這個線程私有的結構里面保存的是什么呢?我們可以從mtdll.h中找到它的定義,它里面保存的是諸如線程ID、線程句柄、erron、strtok()的前一次調用位置、rand()函數的種子、異常處理等與CRT有關的而且是線程私有的信息。可見MSVC CRT并沒有使用我們前面所說的__declspec(thread)這種方式來定義線程私有變量,從而防止庫函數在多線程下失效,而是采用在堆上申請一個_tiddata結構,把線程私有變量放在結構內部,由顯式TLS保存_tiddata的指針。

了解了這些信息以后,我們應該會想到一個問題,那就是如果我們用CreateThread()創建一個線程然后調用CRT的strtok()函數,按理說應該會出錯,因為strtok()所需要的_tiddata并不存在,可是我們好像從來沒碰到過這樣的問題。查看strtok()函數就會發現,當一開始調用_getptd()去得到線程的_tiddata結構時,這個函數如果發現線程沒有申請_tiddata結構,它就會申請這個結構并且負責初始化。于是無論我們調用哪個函數創建線程,都可以安全調用所有需要_tiddata的函數,因為一旦這個結構不存在,它就會被創建出來。

那么_tiddata在什么時候會被釋放呢?ExitThread()肯定不會,因為它根本不知道有_tiddata這樣一個結構存在,那么很明顯是_endthread()釋放的,這也正是CRT的做法。不過我們很多時候會發現,即使使用CreateThread()和ExitThread() (不調用ExitThread()直接退出線程函數的效果相同),也不會發現任何內存泄露,這又是為什么呢?經過仔細檢查之后,我們發現原來密碼在CRT DLL的入口函數DllMain中。我們知道,當一個進程/線程開始或退出的時候,每個DLL的DllMain都會被調用一次,于是動態鏈接版的CRT就有機會在DllMain中釋放線程的_tiddata。可是DllMain只有當CRT是動態鏈接版的時候才起作用,靜態鏈接CRT是沒有DllMain的!這就是造成使用CreateThread()會導致內存泄露的一種情況,在這種情況下,_tiddata在線程結束時無法釋放,造成了泄露。

我們可以用下面這個小程序來測試:

復制代碼 代碼如下:
#include <Windows.h>
#include <process.h>
void thread(void *a)
{
??? char* r = strtok( "aaa", "b" );
??? ExitThread(0); // 這個函數是否調用都無所謂
}
int main(int argc, char* argv[])
{
??? while(1) {
??????? CreateThread(? 0, 0, (LPTHREAD_START_ROUTINE)thread, 0, 0, 0 );
??????? Sleep( 5 );
??? }
return 0;
}

如果用動態鏈接的CRT (/MD,/MDd)就不會有問題,但是,如果使用靜態鏈接CRT (/MT,/MTd),運行程序后在進程管理器中觀察它就會發現內存用量不停地上升,但是如果我們把thread()函數中的ExitThread()改成_endthread()就不會有問題,因為_endthread()會將_tiddata()釋放。

這個問題可以總結為:當使用CRT時(基本上所有的程序都使用CRT),請盡量使用_beginthread()/_beginthreadex()/_endthread()/_endthreadex()這組函數來創建線程。在MFC中,還有一組類似的函數是AfxBeginThread()和AfxEndThread(),根據上面的原理類推,它是MFC層面的線程包裝函數,它們會維護線程與MFC相關的結構,當我們使用MFC類庫時,盡量使用它提供的線程包裝函數以保證程序運行正確。

總結

以上是生活随笔為你收集整理的CreateThread()与beginthread()的区别详细解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲色偷偷综合亚洲av伊人 | 91中文字日产乱幕4区 | 日本一区二区在线免费观看 | 免费的黄色一级片 | 黄色激情网站 | 中文字幕另类 | 国产v片在线观看 | 就要操就要日 | 夜夜操免费视频 | 五月网站| 天天射夜夜 | 欧美激情va永久在线播放 | 爱福利视频网 | 天海翼一区二区 | 欧美日本成人 | 精品视频久久久 | 精品人妻少妇AV无码专区 | 亚洲人成7777 | 国产日本精品视频 | 亚洲国产精品国自产拍久久 | 口爆吞精一区二区三区 | 少妇太紧太爽又黄又硬又爽小说 | 日韩欧美视频一区二区三区 | 六月婷婷久久 | 欧美整片在线观看 | 日韩美女少妇 | 久久久久91| 日本美女毛片 | 亚洲爆爽av | 特级大胆西西4444人体 | av片毛片 | 性欧美在线视频 | 亚洲精品区 | 密臀av在线播放 | 一区二区免费在线播放 | 亚洲一区二区三区中文字幕 | 请用你的手指扰乱我吧 | 放荡的少妇2欧美版 | 成人影视网址 | 99爱99| 精品在线播放视频 | 国产欧美一区二区三区在线看 | 日韩一区二区精品视频 | 樱空桃在线 | 成人高清视频免费观看 | 国产一区二区在线免费 | 国产极品999 | 男男巨肉啪啪动漫3d | 91人人澡人人爽人人精品 | 亚洲成人aaa | 亚洲毛片久久 | 88av网站 | 婷婷久久亚洲 | 国产不卡在线播放 | 亚洲精品国产精华液 | 久久亚洲一区二区三区四区五区 | 激情久久久 | 亚洲永久免费精品 | 日本a在线免费观看 | 毛片.com | 黄色片久久 | 国产欧美激情在线观看 | 丁香七月激情 | 日批视频免费在线观看 | 欧美黄在线观看 | 怡红院久久 | 香蕉茄子视频 | 欧美中文字幕一区二区 | 日日天天干 | 黄色免费一级视频 | 办公室摸腿吻胸激情视频 | 国内精品久久久久久久久久久 | 久久草视频在线 | 国产亚洲色婷婷久久 | 色av综合网 | 在线视频 日韩 | 日韩123 | 国精产品一区一区三区mba下载 | 91精品国产综合久久久蜜臀 | 激情欧美亚洲 | 涩涩涩涩涩涩涩涩涩涩 | 久久综合久久网 | 91午夜影院 | 色网站入口 | 国产精品久久久久久久久久久久久久久久久 | 欧美成人91| 久青草视频 | 欧美性猛交xxxx乱大交俱乐部 | 国产一区二区三区在线 | 欧美成人h版在线观看 | 国产欧美一区二区三区另类精品 | 香蕉视频色版 | 亚洲综合av一区二区 | 麻豆短视频在线观看 | 国产视频999| 欧美区二区三区 | 91传媒网站 | 国产精品99久久久久久久女警 | 亚洲三级小视频 |