核心編程6——線程

Note 0:
進程實際是由兩個組件組成的:一個進程內核對象和一個地址空間.類似地,線程也由兩個組件組成:
一個是線程的內核對象,操作系統用它管理線程.內核對象還是系統用來存放線程統計信息的地方.
一個線程堆棧,用于維護線程執行時所需的所有函數參數和局部變量.
Note 1:
進程是有惰性的.進程從來不執行任何東西,它只是一個線程的容器.線程必然是在某個進程的上下文中創建的,而且會在這個進程內部"終其一生".這意味著線程要在其進程的地址空間內執行代碼和處理數據.此外,這些線程還共享內核對象句柄,因為句柄表是針對每一個進程的,而不是針對每一個線程.相較于線程,進程所使用的系統資源更多.其原因在于地址空間.為一個進程創建一個虛擬的地址空間需要大量系統資源.系統中會發生大量的記錄活動,而這需要用到大量內存.而且,由于.exe和.dll文件要加載到一個地址空間,所以還需要用到文件資源.另一方面,線程使用的系統資源要少得多.事實上,線程只有一個內核對象和一個堆棧;幾乎不涉及記錄活動,所以不需要占用多少內存.
Note 2:
線程描述了進程內部的一個執行路徑.每次初始化進程時,系統都會創建一個主線程.對于用Microsoft C/C++編譯器生成的應用程序,這個線程首先會執行C/C++運行庫的啟動代碼,后者調用入口函數(_tmain或_tWinMain),并繼續執行,直至入口函數返回C/C++運行庫的啟動代碼,后者最終將調用ExitProcess.對于許多應用程序來說,這個主線程是應用程序惟一需要的線程.但是,進程也可以創建額外的線程來幫助它們完成自己的工作.

Note 3:
操作系統的Windows Indexing Services(Windows索引服務)創建了一個低優先級的線程.此線程定期醒來.并對硬盤上的特定區域的文件內容進行索引.Windows索引服務極大改進了性能.因為一旦成功建立索引.就不必在每次搜索時都打開、掃描和關閉硬盤上的每一個文件.配合這種索引服務.Microsoft Windows Vista提供了一套高級的搜索功能.

Note 4:
如果想創建一個或
多個輔助線程.只需讓一個正在運行的線程調用CreateThread:
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
DWORD cbStackSize,
PTHREAD_START_ROUTINE pfnStartAddr,
PVOID pvParam,
DWORD dwCreateFlags,
PDWORD pdwThreadID);
調用CreateThread時.系統會創建一個線程內核對象.這個線程內核對象不是線程本身.而是一個較小的數據結構.操作系統用這個結構來管理線程.可以把線程內核對象想象為一個由線程統計信息構成的小型數據結構.這與進程和進程內核對象之間的關系是相同的
系統將進程地址空間的內存分配給線程堆棧使用.新線程在與負責創建的那個線程相同的進程上下文中運行.因此.新線程可以訪問進程內核對象的所有句柄、進程中的所有內存以及同一個進程中其他所有線程的堆棧.這樣一來.同一個進程中的多個進程可以很容易地互相通信.
Note 5:
CreateThread函數是用于創建線程的Windows函數.不過.如果寫的是C/C++代碼.就絕對不要調用CreateThread.相反.正確的選擇是使用Microsoft C++運行庫函數_beginthreadex.如果使用的不是Microsoft C++編譯器.你的編譯器的提供商應該提供類似的函數來替代CreateThread.不管這個替代函數是什么.都必須使用它.

Note 6:
使用鏈接器的/STACK開關來控制線程堆棧使用多少地址空間.如下所示:
/STACK:[reserve] [,commit]
reserve參數用于設置系統將為線程堆棧預留多少地址空間.默認是1 MB(在Itanium芯片組上.默認大小為 4 MB).commit參數指定最初應為堆棧的保留區域提交多少物理存儲空間.默認是1頁.隨著線程中的代碼開始執行.需要的存儲空間可能不止1頁.如果線程溢出它的堆棧.會產生異常.(有關線程堆棧和堆棧溢出異常的詳情.請參見第16章.有關常見異常處理的詳情.請參見第23章.)系統將捕獲這種異常.并將另一個頁(或者為commit參數指定的任何大小)提交給保留空間.這樣一來.線程堆棧就可以根據需要動態地增大.
Note 7:
保留空間的容量設定了堆棧空間的上限.這樣才能捕獲代碼中的無窮遞歸bug.例如.假設你寫了一個函數以遞歸方式調用其自身.而且這個函數存在一個bug.會導致無窮遞歸.每次此函數調用自身時.都會在內存堆棧上創建一個新的堆棧幀.如果系統沒有設定堆棧空間的上限.這個遞歸調用的函數就永遠不會終止調用自身.進程的所有地址空間都會被分配出去.大量物理存儲會提交給堆棧.通過設置堆棧空間的上限.可以防止應用程序耗盡物理內存區域.而且還可以盡早察覺程序中的bug.
Note 8:
創建多個線程時.可以讓它們使用同一個函數地址作為起點.這樣做完全合法.而且非常有用.(可以傳遞了不同的pvParam值,來區分不同的線程所調用相同的函數.)

Note 9:
TerminateThread函數是異步的.也就是說.它告訴系統你想終止線程.但在函數返回時.并不保證線程已經終止了.如果需要確定線程已終止運行.還需要調用WaitForSingleObject或類似的函數.并向其傳遞線程的句柄.
Note 10:
如果通過返回或調用ExitThread函數的方式來終止一個線程的運行.該線程的堆棧也會被銷毀.但是.如果使用的是TerminateThread.那么除非擁有此線程的進程終止運行.否則系統不會銷毀這個線程的堆棧.Microsoft故意以這種方式來實現TerminateThread.否則.假如其他還在運行的線程要引用被"殺死"的那個線程的堆棧上的值.就會引起訪問沖突.讓被"殺死"的線程的堆棧保留在內存中.其他的線程就可以繼續正常運行.
此外.動態鏈接庫(DLL)通常會在線程終止運行時收到通知.不過.如果線程是用TerminateThread強行"殺死"的.則DLL不會收到這個通知.其結果是不能執行正常的清理工作.
Note 11:
線程終止運行時.會發生下面這些事情:
線程擁有的所有用戶對象句柄會被釋放.在Windows中.大多數對象都是由包含了"創建這些對象的線程"的進程擁有的.但是.一個線程有兩個User對象:窗口(window)和掛鉤(hook).一個線程終止運行時.系統會自動銷毀由線程創建或安裝的任何窗口.并卸載由線程創建或安裝的任何掛鉤.其他對象只有在擁有線程的進程終止時才被銷毀.
線程的退出代碼從STILL_ACTIVE變成傳給ExitThread或TerminateThread的代碼.
線程內核對象的狀態變為signaled.
如果線程是進程中的最后一個活動線程.系統認為進程也終止了.
線程內核對象的使用計數遞減1.

Note 19:
對CreateThread函數的一個調用導致系統創建一個線程內核對象.該對象最初的使用計數為2.(除非線程終止,而且從CreateThread返回的句柄關閉,否則線程內核對象不會被銷毀.)該線程內核對象的其他屬性也被初始化:暫停計數被設為1,退出代碼被設為STILL_ACTIVE (0x103),而且對象被設為nonsignaled狀態.
Note 20:
一旦創建了內核對象,系統就分配內存,供線程的堆棧使用.此內存是從進程的地址空間內分配的,因為線程沒有自己的地址空間.然后,系統將兩個值寫入新線程堆棧的最上端.(線程堆棧始終是從高位內存地址向低位內存地址構建的.)寫入線程堆棧的第一個值是傳給CreateThread函數的pvParam參數的值.緊接在它下方的是傳給CreateThread函數的pfnStartAddr值.
Note 21:
每個線程都有其自己的一組CPU寄存器,稱為線程的上下文(context).上下文反映了當線程上一次執行時,線程的CPU寄存器的狀態.線程的CPU寄存器全部保存在一個CONTEXT結構(在WinNT.h頭文件中定義).CONTEXT結構本身保存在線程內核對象中.
Note 22:
當線程的內核對象被初始化的時候,CONTEXT結構的堆棧指針寄存器被設為pfnStartAddr在線程堆棧中的地址.而指令指針寄存器被設為RtlUserThreadStart函數(該函數未見于正式文檔)的地址,此函數是NTDLL.dll模塊導出的.
RtlUserThreadStart函數的基本用法如下:
VOID RtlUserThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam) {
__try {
ExitThread((pfnStartAddr)(pvParam));
}
__except(UnhandledExceptionFilter(GetExceptionInformation())) {
ExitProcess(GetExceptionCode());
}
// NOTE: We never get here.
}
Note 23:
線程完全初始化好之后,系統將檢查CREATE_SUSPENDED標志是否傳給CreateThread函數.如果此標記沒有傳遞,系統將線程的暫停計數遞增至0;隨后,線程就可以調度給一個處理器去執行.然后,系統在實際的CPU寄存器中加載上一次在線程上下文中保存的值.現在,線程可以在其進程的地址空間中執行代碼并處理數據了.
Note 24:
新線程執行RtlUserThreadStart函數的時候,將發生以下事情:
圍繞你的線程函數,會設置一個結構化異常處理(Structured Exception Handling,SEH)幀.這樣一來,線程執行期間所產生的任何異常都能得到系統的默認處理.
系統調用你的線程函數,把你傳給CreateThread函數的pvParam參數傳給它.
線程函數返回時,RtlUserThreadStart調用ExitThread,將你的線程函數的返回值傳給它.線程內核對象的使用計數遞減,而后線程停止執行.
如果線程產生了一個未被處理的異常,RtlUserThreadStart函數所設置的SEH幀會處理這個異常.通常,這意味著會向用戶顯示一個消息框,而且當用戶關閉此消息框時,RtlUserThreadStart會調用ExitProcess來終止整個進程,而不只是終止有問題的線程.
Note 25:
當RtlUserThreadStart開始執行時,它會調用C/C++運行庫的啟動代碼,后者初始化繼而調用你的_tmain或_tWinMain函數.你的入口函數返回時,C/C++運行時啟動代碼會調用ExitProcess.所以對于C/C++應用程序來說,主線程永遠不會返回到RtlUserThreadStart函數.
Note 26:
Visual Studio附帶了4個原生的C/C++運行庫,還有2個庫面向Microsoft.NET的托管環境.注意,所有這些庫都支持多線程開發:不再有單獨的一個C/C++庫專門針對單線程開發.下面對這些庫進行了描述.
Microsoft Visual Studio附帶的C/C++庫
庫名稱????? 描述
LibCMt.lib?? 庫的靜態鏈接Release版本
LibCMtD.lib 庫的靜態鏈接Debug版本
MSVCRt.lib?? 導入庫,用于動態鏈接MSVCR80.dll 庫的Release版本. (這是新建項目時的默認庫)
MSVCRtD.lib 導入庫,用于動態鏈接MSVCR80D.dll庫的Debug版本
MSVCMRt.lib 導入庫,用于托管/原生代碼混合
MSVCURt.lib 導入庫,編譯成百分之百純MSIL代碼

-------------------------------------------------------------------

?

?

轉載于:https://www.cnblogs.com/lzjsky/archive/2010/06/04/1751719.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276046.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PHP解決搶購、秒殺、搶樓、抽獎等阻塞式高并發庫存防控超量的思路方法

轉載鏈接:http://www.4u4v.net/thinking-approach-to-buy-spike-grab-floor-sweepstakes-and-other-high-concurrent-blocking-prevention-excess-inventory-solve-php.html 如今在電商行業里,秒殺搶購活動已經是商家常用促銷手段。但是庫存數量有限,而同…

看了就會的 Node.js 三大基礎模塊常用 API

大家好,我是若川。歡迎加我微信 ruochuan12,加群交流學習。今天分享一篇nodejs基礎的文章。點擊下方卡片關注我,或者查看源碼等系列文章。在日常使用 Node 進行開發的時候,會使用到一些文件系統、路徑操作等基礎 API,這…

vue-cli3插件初體驗

vue-cli3發布自2018年8月,距離現在還不是特別久,最好搭建項目剛好用到,所以寫下這篇文章,記錄一下踩坑經歷。vue的作者說過,vue-cli的本質是模版的拉取,太多的配置導致了模版的難以維護,所以重構…

ios設計登錄功能_親愛的產品設計師,這是iOS 14的新功能

ios設計登錄功能On June 22, 2020 Apple previewed iOS 14 for the first time. As always there are quite some changes you should know about as a product designer like widgets, pickers, app clips, permissions and more.2020年6月22日,Apple首次預覽iOS 1…

c++ int 轉 short_C/C++結構體內存對齊

在面試或工作中,經常會遇到內存對齊的問題。這里結合我的理解談一談對內存對齊的理解。1. 為什么要內存對齊,不對齊會怎么樣?內存中存放數據是為了給CPU使用,CPU訪問內存數據時會受到地址總線寬度的限制,也就是一次能從…

對于日訪問量達到1W IP的處理方法

轉自:http://www.java123.net/56026-2.html 對于日訪問量達到1W IP的處理方法 一、1萬ip真是不高: 1.常用數據用緩存,減輕數據庫壓力。 2.詳細頁數據生成靜態頁面。 二、10000算是相當小的了,不需要什么特殊的處理機制,只要符合最一般的…

數據契約(DataContract)

WCF第一要素就是契約: 服務契約用于聲明可用于遠程訪問的類型。在Interface或class開始處使用服務契約標簽. [ServiceContract] Public interface Iservice { } 接口調用契約的好處: 1. 同一服務類型可以實現多個不相干的服務契約. 2. 有利于版本升級 3. 按照…

jakob slam_Jakob Nielsen針對用戶界面設計的第二種可用性啟發法

jakob slamIn the pursuit of providing great user experiences, it’s imperative that digital products are evaluated. A 為了提供出色的用戶體驗,必須對數字產品進行評估。 一個 heuristic evaluation is essential to delivering great user experiences. I…

微軟Office 365正式上架Mac App Store

今天,Office 365正式在Mac App Store上架,Mac用戶可以輕松下載Word,Outlook,Excel,PowerPoint,OneNote以及整套微軟的熱門應用程序。用戶還可以從應用程序內訂購Office 365。蘋果全球開發者關系高級主管Sha…

一文搞懂瀏覽器原理

大家好,我是若川。最近這幾年,云計算的普及和 HTML5 技術的快速發展,越來越多的應用轉向了瀏覽器 / 服務器(B/S)架構,這種改變讓瀏覽器的重要性與日俱增,視頻、音頻、游戲幾大核心場景也都在逐漸…

python處理excel可視化_python如何將excel數據處理可視化

python將excel數據處理可視化的方法:首先安裝xlrd與xlwt庫,進行表格讀取;然后使用pyecharts生成Echarts圖表的類庫;最后安裝Echarts讀取Excel數據及顯示即可。python將excel數據處理可視化的方法:Excel表操作python操作…

dataframe中將一列數據切分成多列

為什么80%的碼農都做不了架構師&#xff1f;>>> 原sheet中數據 目的 將【備注】列切分成【key】列和【value】列 Python sheet[key] sheet[備注].str.extract(r(_.*(?\u503c))) sheet[value] sheet[備注].str.extract(r((?<).*))結果 參考 pandas.Series.st…

matplotlib可視化_EDA:Geopandas,Matplotlib和Bokeh中的可視化

matplotlib可視化Nowadays, everyone is immersed with plenty of data from news sources, cellphones, laptops, workplaces, and so on. Data conveys with tons of information from different data variables like date, string, numeric, and geographical format. How t…

(轉)結婚那天,媽問我:坐在角落里象兩個要飯模樣的人是誰?

人人看到的文章 很感人~~~~結婚那天&#xff0c;媽問我&#xff1a;坐在角落里象兩個要飯模樣的人是誰&#xff1f; 我看過去的時候&#xff0c;有個老頭正盯著我&#xff0c;旁邊還有個老太太&#xff0c;發現我看著他們時趕忙低下頭。我不認識他們但也不象要飯的&#xff0c;…

nginx-1.13.x源碼安裝

Nginx 安裝配置【依賴庫】[ zlib ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id24013&ResourceID12241 [ pcre ]apt-get install libpcre-dev[ openssl ]&#xff08;下載&#xff09;http://download.chinaunix.net/download.php?id3937…

小技巧!CSS 整塊文本溢出省略特性探究

大家好&#xff0c;我是若川。歡迎加我微信 ruochuan12&#xff0c;長期交流學習。今天的文章很有意思&#xff0c;講一講整塊文本溢出省略打點的一些有意思的細節。點擊下方卡片關注我&#xff0c;或者查看源碼系列文章。文本超長打點我們都知道&#xff0c;到今天&#xff08…

linux配置ip地址 suse_SUSE Linux下設置IP的兩種方法

第一種SUSE Linux IP設置方法ifconfig eth0 192.168.1.22 netmask 255.255.255.0 uproute add default gw 192.168.1.2釋義&#xff1a;#IP配置&#xff0c;包括子網掩碼,看情況修改eth0和192.168.1.22#網關修改 ,看情況修改192.168.1.2第二種SUSE Linux IP設置方法在suse操作系…

寒假作業3:抓老鼠啊

7-1 抓老鼠啊~虧了還是賺了&#xff1f; &#xff08;20 分&#xff09; 某地老鼠成災&#xff0c;現懸賞抓老鼠&#xff0c;每抓到一只獎勵10元&#xff0c;于是開始跟老鼠斗智斗勇&#xff1a;每天在墻角可選擇以下三個操作&#xff1a;放置一個帶有一塊奶酪的捕鼠夾(T)&…

筆記本移交_創建完美的設計移交

筆記本移交重點 (Top highlight)Design specifications (specs) are guidelines that developers will use to implement a design. Think of an architect providing building blueprints to the construction team. Many designers think of specs as mindless zombie work. …

大手筆,送¥1599的Apple AirPods Pro和獨家禮物等

大家好&#xff0c;我是若川。為感謝公眾號讀者們長久以來的支持&#xff0c;本次我聯合幾位前端界大佬給大家送超級福利了。除了聯合福利之外&#xff0c;每位前端大佬還帶了專屬禮品送給大家&#xff0c;所有抽獎均可重復參與、可重復中獎&#xff0c;詳情見下文每個公眾號的…