執行緒區域性儲存,Part 1 概述

2021-06-12 02:46:35 字數 1119 閱讀 2887

原文**:

和其它主流多執行緒作業系統一樣,windows為大家提供乙個機制,該機制允許程式設計師實現基於執行緒的區域性狀態儲存。這種能力通常稱為執行緒區域性儲存(thread local storage,tls),這對於那些需要儲存執行緒相關資訊但需要全域性可見的應用場景非常有用。

儘管tls的介紹有很好的文件可參考,但關於其實現細節的介紹並不多(儘管也有一些非官方文件進行比較表面的介紹)。

至少從高層來將,tls在概念上並不複雜。常規設計是將所有對tls的訪問都通過teb中的指標來進行間接訪問,teb為作業系統定義的每個執行緒乙份的資料結構,用於儲存一些執行緒相關的資訊。

在非x86和非x64架構中,訪問teb的底層機制是不同的,但是通常也是使用暫存器存放teb的位址,從而使其更易於訪問。

teb本身可算是windows中文件化最好的未公開結構,這主要是因為在最近構建的ntdll和ntoskrnl中該結構為偵錯程式提供了一些型別資訊(type information)。通過這些資訊和一點反彙編工作,即可很容易的理解tls的背後的實現細節。

在著手了解tls如何工作之前,有必要看一下其文件化的使用方法。首先是通過kernel32中的一組用於顯示使用tls的函式:tlsgetvalue、tlssetvalue、tlsalloc、tlsfree。這些函式的使用非常直觀。tlsalloc為所有執行緒預留乙個指標大小的空間,tlsgetvalue用於讀取執行緒相關的變數。(其它兩個函式完成功能類似)。

其次,是由載入器、編譯器和鏈結器所支援的隱式使用執行緒區域性儲存的方法,方法是在變數上加__declspec(thread)修飾。這比使用tls apis要方便的多,因為不需要每次都使用tls函式去訪問執行緒區域性儲存變數。這種方式同樣解除了需要顯示呼叫tlsalloc和tlsfree的困擾,提供了一種有效的使用執行緒區域性儲存的方式(隱式tls通過分配一大塊記憶體來實現,記憶體大小由所有執行緒區域性變數占用空間總和,對於乙個模組中的所有執行緒區域性變數僅需要在tls陣列中的乙個索引就可以了)。

既然隱式tls具有這些優點,那為何我們需要顯示tlsapi了?原因是在vista之前,在載入器的tls實現中含有一些討厭的限制。尤其是隱式tls在模組不是在程序初始化時載入會不起作用(即不能動態載入或延遲載入)。這意味著在實際應用當中除了exe檔案和保證會靜態連線的dll庫,其它都無法使用。

下回:近觀顯式tls和其工作的機制。

部落格推薦 Part 1

部落格推薦 part 1 博起 了一年多了,寫過一百多篇博文,看過的博文更是不計其數。剛剛看到乙個部落格的文章,實在把我笑到不行。然後就想推薦給大家。繼而就心血來潮,想把自己喜歡的一些部落格陸續的推薦給大家。也許,你也會喜歡呢?說明 仙仙,本名張仙!是湖南的一位autoware兄弟,跟我一起混跡內蒙...

C Handle 控制代碼 part1

本文是我學習c 沉思錄第6章的筆記 本文主要講述了handle類的概念,定義方法以及寫時複製技術。在前文 surrogate 類 的講解中我們了解到了 的實現方法.類有很多好處,但是麻煩的是每次都得進行複製.如果該類是經常使用並且member很多的話,這樣複製的消耗是十分客觀的.因此這裡就要介紹另外...

目標檢測part1

1 1卷積 googlenet inception 可看作全連線 1 增加非線性 2 特徵降維 空洞卷積 在相同的感受野的情況下,使用空洞卷積得到更大的特徵圖,獲得更密集的資料,而更大的特徵圖有助於目標檢測和目標分割任務中對小物體的識別分割效果 轉置卷積 不是真正意義上的反卷積,是一種上取樣的方式,...