原文連接在印象筆記(效果也好的多):https://app.yinxiang.com/l/AAQlNLnxTPRMAppVr5W0upchipQDDC_FHlU數據結構
- 概要:
-
- 現成也有兩個組成部分:
-
- 現成的內核對象,操做系統用它管理現成。系統還用內核對象來存放現成統計信息的地方
- 線程棧,用於維護現成執行時所需的全部函數參數和局部變量
- 進程歷來不執行任何東西,它只是一個線程的容器
- 現成必然是在某個進程的上下文中建立的,線程要在其進程的地址空間內執行代碼和處理數據
- 線程還共享內核對象句柄,句柄表是針對每個進程的,而不是針對每個線程
- 6.1 什麼時候建立線程
-
- 線程描述了進程內部的一條執行線路。
- 每次初始化進程時,系統都會建立一個主線程
- 多線程簡化了應用程序的用戶界面的設計
- 6.2 什麼時候不該該建立線程
- 6.3 編寫第一個線程函數
-
- 6.4 CreateThread函數(系統如何建立一個線程)
-
- 調用CreateThread時,系統會建立一個線程內核對象。這個線程內核對象不是線程自己,而是一個較小的數據結構,操做系統利用這個結構來管理線程
- 6.4.1 psa參數:是一個指向SECURITY_ATTRIBUTES結構的指針
- 6.4.2 cbStackSize參數:指定線程能夠爲其線程棧使用多少地址空間。
-
- 線程的動態增加:存儲空間超過1個頁面,致使線程溢出它的棧,會產生異常。系統捕獲後的同時爲空間區域調撥另外一個頁面,從而實現線程的動態增大。
- 線程的存儲空間:
- 線程棧,線程棧預留地址空間
- 預約空間的大小要麼由/STACK鏈接器開關指定,要麼由cbStack Size的值來指定,取其中較大的哪個
- 棧空間的上限:不只能夠放置應用程序耗盡物理內存區域,並且還能夠儘早察覺程序中的bug
- 6.4.3 pfnStartAddr和pvParam參數
-
- pfnStartAddr參數指定但願新線程執行的縣城函數的地址
- pvParam參數與最初傳給CreateTread的pvParam參數是同樣的
- Windows是一個槍戰士的多線程系統,這意味着新的線程和調用CreateThread函數的線程能夠同時執行,由於這兩個線程是同時運行的
- 當A線程已經closeHandle,B線程試圖去更改現已無效的一個地址內容,這會致使線程B穿上你生訪問違規,緣由在於線程A的棧已在A終止運行時被銷燬。
- 使用靜態變量也不能解決問題,會致使函數不可重用,由於兩個線程將共享一個靜態變量。
- 6.4.4 dwCreateFlags:指定額外的標誌來控制線程的建立
-
- 值0:線程建立以後當即就能夠進行調度
- 值CREATE_SUSPENDED:系統將建立並初始化線程,可是會暫停該線程的運行,這樣它就沒法被調度
- 備註:經過不一樣的方式來控制線程可否在建立以後立刻被調度
- 6.4.5 pdwThreadID:
-
- 它必須是DWORD的一個有效地址
- CreateThread函數用它來存儲系統分配給新線程的ID(通常傳NULL)
- 6.5 終止運行線程
-
- 四種終止線程運行的方法:
- 6.5.1 線程函數返回:保證線程的全部資源都被正確清理的惟一方式
- 6.5.2 ExitThread函數
-
- 不推薦使用
- 操做系統會清理該線程使用的全部操做系統資源
- C/C++資源不會被銷燬
- 6.5.3 TerminateThread函數
-
- 不一樣於ExitTread老是殺死主調線程,TerminateThread函數能殺死任何線程
- 函數是異步的。它告訴系統你想終止線程,但在函數返回時,並不保證線程已經終止。若是須要肯定線程已終止運行,還須要調用WaitForSingleObject或相似的函數,並向其傳遞線程的句柄
- 爲了良好的設計,不要使用。緣由是被停止運行的線程收不到它被殺死的通知。線程沒法正確清理,並且不能阻止本身被終止運行
- 擴展名字解釋:線程的堆棧