關於threadlocal的來龍去脈

引用其他麻油的評論:

對TLS更簡單的,但是更直觀的理解可以如下(基於C語言):

1. 全局對象,全局變量的作用域和生命週期是全局的,這裏的全局是指進程範疇,也就是說,如果你將其設計爲全局對象,全局變量,就意味着你希望在多線程的環境中,仍然能共享和訪問。 全局對象,全局變量不是說不讓多線程來訪問,而是說有的時候不期望他們同時訪問,此時引入了線程的互斥,互斥的後果是保證不同時訪問,但是,並沒有改變共享的本質!
--------------這裏應該說的是synchronized
2. 如果設計的時候,就希望將某個對象,變量設計爲線程局部的,那典型的是可以將其設計爲函數的局部變量。 可是,我如果又希望在線程執行時,任意的函數和對象裏面都可以訪問到它那?! 此時,可能會想到用全局對象,全局變量,但是,它又會使得這種訪問域上升到進程級別,其實,我只是想在線程局部環境中,全局訪問該對象。 此時TLS應運而生,TLS就是達到了這種, 在線程局部環境(或者稱呼爲線程執行環境,線程上下文)下可以全局訪問的對象/變量。
------------這裏應該說的是threadlocal了
關於TLS的實際應用,更多的是定義一個TLS對象來存儲一些線程上下文相關的信息。


給你取這樣一個典型的例子吧,你可以看到TLS實際的應用場合。

在一個支持單進程,多線程的輕量級移動平臺中,假設我實現了一個APP Framework,每一個APP單獨運行在一個獨立的線程中,APP運行時關聯了很多信息,比如打開的文件,引用的組件,啓動的Timer等等。我希望框架能實現自動垃圾回收,什麼概念,就會應用退出的時候,即便應用沒有主動釋放打開的文件句柄,沒有主動cancel Timer,沒有主動釋放組件的引用,框架也可以自動完成這些收尾工作,否則,後果是不堪想象的。 

好了,假設應用的退出是調用了框架的 ExitApp API, 該API允許應用調用後關閉自己,也允許關閉別的應用。 那麼,假設該API觸發了應用的退出,最終調用到框架的App_CleanUp函數,那麼App_CleanUp函數除了完成應用本身實例的釋放外,肯定是在這裏來完成我們上面說的收尾工作,怎麼來做哪?! 很明顯,這裏典型的,就可以使用TLS了。具體如下:

在Framework的API中,當應用的線程啓動時,New 一個AppContext的對象或者結構體,然後將對象的指針或者結構體的指針以TLS的方式存儲起來。 AppContext內部包含了文件句柄,timer引用,組件引用等等。 然後,後續任何框架的文件操作/Timer操作時,取當前線程的TLS,然後轉換成AppContext後,將更新的文件句柄,timer引用等更新入AppContext對象內部。 然後,應用退出時,獲取TLS,然後轉換成AppContext,取出非空的文件句柄,組件引用,Timer引用等,來完成Cancel和Close操作。


其他不想說了,如果你能明白這個實際的例子,你就可以明白TLS的用途了。 上述的例子,來源於BREW/BMP框架內部的實際實現,當然有差別,但是思想是一樣的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章