linux線程有時候起不來,linux thread model

 2023-11-12 阅读 30 评论 0

摘要:Linux上posix線程庫實現原理討論 說明一下,這個問題困擾我好長時間,因為正如使用C編程會希望了解進程的內存映象一樣,使用POSIX線程庫我們也會想去了解其實現的原理。目前只是查過一些資料,或許仍然有誤解的地方,請大家繼續指正 :) ? ?? ?
Linux上posix線程庫實現原理討論

說明一下,這個問題困擾我好長時間,因為正如使用C編程會希望了解進程的內存映象一樣,使用POSIX線程庫我們也會想去了解其實現的原理。目前只是查過一些資料,或許仍然有誤解的地方,請大家繼續指正 :)

? ?? ?首先我們需要了解線程(threads)是個什么概念。在傳統UNIX中,進程(process,就是Intel所謂的task)是調度的最小單位,復雜的大型軟件往往需要有多個進程,fork+exev是很常用的技巧。但是隨著需求的擴大,特別是網絡服務的復雜性增長,fork的開銷就成為一個瓶頸問題。為此產生了vfork和copy-on-write技術,都是為了減小fork的開銷。linux線程有時候起不來。
? ?? ?pthreads的引入也是為了解決fork開銷問題,同時能夠支持SMP(對稱多處理器)。在SMP機器上,一個進程內的多個線程可以分布在各個處理器上并行運行。
? ?? ?由于歷史原因,2.5.x以前的linux對pthreads沒有提供內核級的支持,所以在linux上的pthreads實現只能采用n:1的方式,也稱為庫實現。下面先說一下pthreads的3種實現方式。
Linux上posix線程庫實現原理討論

pthreads的實現有3種方式:
第一,多對一,也就是庫實現。threadlocal詳解,模型圖如下。

這種實現沒有OS的支持,線程對OS來說是不可見的,OS不知道線程的存在與否,也不負責對它們進行調度。所有的此類工作由線程庫來完成。
可想而知,既然調度不是由OS進行的,那么SMP機器的優勢完全用不上。一個進程只能運行在一個CPU上,不管它包含多少線程。shell進程、

Linux上posix線程庫實現原理討論

第二種,1:1模式。(好象Solaries就是這種模式?)

1:1模式中,每個線程對應存在一個內核線程。也就是說,OS知道每個線程的生老病死,對它們進行調度。
1:1模式適合CPU密集型的機器。我們知道,進程(線程)在運行中會由于等待某種資源而阻塞,可能是I/O資源,也可能是CPU。java Thread?在多CPU機器上1:1模式是個很不錯的選擇。因此1:1的優點就是,能夠充分發揮SMP的優勢。
這種模式也有它的缺點。由于OS為每個線程建立一個內核線程,導致內核級的內存空間(IA32機器的4G虛存空間的最高1G)的大開銷。第二個缺點在于,在傳統意義上,在mutex互斥鎖和條件變量上的操作要求進入內核態,這是因為OS負責調度,它要為線程的轉態轉換負全責。linux?后面我們會看到,Linux的NPTL庫避免了這個缺點,它的互斥鎖與條件變量的操作在用戶態完成。

下面是1:1模式的示意圖:

Linux上posix線程庫實現原理討論

第三種,M:N模式。
這種模式試圖兼有上面2種模式的優點。它要求一個分層的模型。比方說,某個進程內有4個線程,其中每2個線程對應一個內核線程。linux最多多少線程?這樣,OS知道2個實體的存在,負責它們的調度。而在一個實體內有2個線程,這2個線程間的調度就是OS不加干涉、也不知道的了。

簡單的說,M:N模型的OS級調度上,跟1:1模型相似;線程間調度上,跟n:1模型相似。

優點是,既可以在進程內利用SMP的優勢,又可以節省系統空間內存的消耗,而且環境切換大多在用戶態完成。
缺點是顯然的:復雜。rt-thread像linux、

下面是M:N模型的示意圖:

Linux上posix線程庫實現原理討論

下面開始胡說八道了,說說Linux上的posix線程庫實現。這個問題困擾我好長時間,從昨天開始才查了一大堆資料,囫圇理解了一些東西,可能bugs非常多的說 :wink:

1,? ? Linux上的posix線程庫最初實現是n:1模型,就是沒有OS支持的庫實現。這也是狹義上的“LinuxPthreads”,它支持2.0及以后的Linux。Linux Kernel??Mailing List FAQ上一位Hacker曾大大推崇這種方式,拿來與Solaries的1:1模型相比較并證明這種模型是優秀的。至少拿現在的情況來說他的觀點是不正確的。linux線程起不來?這觀點曾讓偶糊涂了很久。

2,? ?IBM公司實現的NGPT。它采用M:N模式,好象與第一種的LinuxPthreads合作工作。

3,? ?NPTL。1:1模型。linux thread、今后Linux平臺的POSIX線程庫事實上的標準實現。
在2002年8、9月份,一直不肯松勁的Linus Torvalds先生終于被說服了,Ingo Molnar把一些重要特性加入到2.5開發版官方內核中。這些特性大體包括:新的clone系統調用,TLS系統調用,posix線程間信號,exit_group(exit的一個變體),等等。有了OS的支持,Ingo Molnar先生同Ulrich Drepper(glibc的LinuxThreads庫的維護者,NPTL的設計者與維護者,現工作于RedHat公司)和其他一些Hackers開始NPTL的完善工作。題外話一句:IBM公司給了他們很大的贊助。實現shell,

在Linux上,可以用getconf GNU_LIBPTHREAD_VERSION來查看你的posix線程庫到底是那一個實現,什么版本。Drepper先生做過測試,據他的測試數據,IA32機器上啟動撤銷10萬個線程,以前的庫實現需要15分鐘,而NPTL只需要2s。

理論上應當是M:N模型最高效,但是Linux內核提供支持后,反倒是1:1模型的NPTL比M:N的NGPT好要快4倍!為什么會這樣呢?目前偶只知道它把環境切換放到用戶態了,別的不懂。

Linux上posix線程庫實現原理討論

支持一下,正在學習MP!后面的繼續!

Linux上posix線程庫實現原理討論

參考:
1。The Native POSIX Thread Library for Linux。thread.currentthread()。Ulrich Drepper的親筆大作,可以從http://people.redhat.com/drepper/nptl-design.pdf下載
2。POSIX多線程程序設計,David Butenhof,中國電力
3。Linux內核源代碼情景分析。不用說了吧?

P.S. 我覺得《情景分析》有一個錯誤,作者在介紹進程時說,
-->

紅色部分顯然是錯誤的。pthreads的必要行完全不能由內核線程取代。docker執行容器內的shell、事實上,倘若這句話正確,pthreads就變成多余的了 :)

Linux上posix線程庫實現原理討論

急需HP-UX下acc的fork, execl的相關知識,我是初學,亟盼任何回復。
謝謝啦!

jjcao@dl.cn

Linux上posix線程庫實現原理討論

問一句,為什么不是kernel process 對應一組屬于這個process的thread?

Linux上posix線程庫實現原理討論

倘若是庫實現那就會象你說的那樣。
即使沒引入pthreads概念,也有很多沒有用戶空間的可調度實體,它們有自己的task_struct,有系統空間堆棧,一般叫它們“kernel thread”。象init和kswapd都是典型的kernel thread。“kernel process”的說法好象不標準哩:-)

Linux上posix線程庫實現原理討論

1:1的這種形式是不是為了以空間換時間?如果N:M的話就需要有一個調度的算法,會降低效率?

Linux上posix線程庫實現原理討論

問樓主一個使用上的問題:
就是設置新的線程棧的地址和大小后,系統不提高保護了(不提高保護了具體是什么意思?),要程序自己保護它的溢出啊什么的,該怎么弄呢?給個思路或給點資料吧,謝謝了:)

Linux上posix線程庫實現原理討論

-->不好意思,我一直都是設為NULL讓實現自己默認的,沒用過這些特性。

Linux上posix線程庫實現原理討論

關于M:N的問題
有一篇論文專門講的,問題的根源在于MEMORY MANAGEMENT部分是在N之間共享的,是CRITICAL SECTION,影響性能(基于SINGEL CPU,或者SHAREDMEMORY MODEL的SMP系統).
對于其他比如CROSS BAR 或者MESH系統來說,M:N性能要好的多.

Linux上posix線程庫實現原理討論

柳兄正好請教個問題,線程的stack是在HEAP區 嗎?

Linux上posix線程庫實現原理討論

user thread的stackS(除了MAIN THREAD外,都在HEAP里面,這里的THREAD LIB在HEAP可以理解成是UNI-PROCESS自己的HEAP空間上開辟的BUFFER).
LIGHT weight process(LWP) THREAD就是CLONE的結果,STACKS就是PROCESS的STACK.
KERNEL THREAD的STACKS基本上都是在HEAP里面分配的.這里THREADS的調度和資源管理寶庫HEAP的管理交給OS KERNEL完成.
THREAD的實現沒有什么標準,各家做法區別很大,但是在API層上是一致的.但是對于具體軟件系統的設計上來說,還是要仔細區分的.特別是對于性能要求很嚴格的東西.

Linux上posix線程庫實現原理討論

>;>;user thread的stackS(除了MAIN THREAD外,都在HEAP里面,
謝謝。不過我想問一下這是POSIX標準規定的嗎?我最近看的文檔好象跟這個說法矛盾。

Linux上posix線程庫實現原理討論

呵呵,是從進程棧那往heap方向生長的

Linux上posix線程庫實現原理討論

再問一個問題,系統對于棧的保護是什么意思?比如由于什么原因棧空間不夠了,這個時候系統做些什么動作呢?難道是僅僅發個棧溢出信號然后讓程序死掉?

Linux上posix線程庫實現原理討論

STACK和HEAP向兩個相反方向擴展,當STACK超過他的SIZE限制,或者STACK到達HEAP的邊界時候,MEMORY不夠,程序退出.
但是有控制系統的專用OS可以在STACK到達HEAP邊的時候,不溢出,而是重新構造STACK一次(盡可能的),---我本人不了解,我同事的觀點.

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/173579.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息