<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Linux多線(xiàn)程編程和Linux 2.6下的NPTL

Linux多線(xiàn)程編程和Linux 2.6下的NPTL

作者: 時(shí)間:2012-05-31 來(lái)源:網(wǎng)絡(luò ) 收藏

這幾天由于工作需要,琢磨了一下下的多的相關(guān)資料。下最常用的多支持庫為 Pthread庫,它是glibc庫的組成部分。但是關(guān)于Pthread的說(shuō)明文檔非常缺乏,特別是對POSIX多規范的介紹以及pthread庫中多線(xiàn)程實(shí)現方式的介紹實(shí)在是少之又少。而多線(xiàn)程對于系統程序員而言是必須掌握的技術(shù),因此總是讓學(xué)習中的程序員覺(jué)得頭痛不以。我自己也沒(méi)有太多多線(xiàn)程的經(jīng)驗,在這里只是把自己收集到的一些關(guān)于上多線(xiàn)程還算新的資料進(jìn)行匯總來(lái)拋磚引玉,以便相互學(xué)習交流。

本文引用地址:http://dyxdggzs.com/article/148957.htm

這里順便提一下市面上有的一本介紹多線(xiàn)程的書(shū)《Posix 多線(xiàn)程》,它是英文版《Programming with POSIX Muiltthread》中譯本,這也是半年前我所能找到的唯一專(zhuān)題介紹多線(xiàn)程編程的書(shū)。我個(gè)人感覺(jué)這本書(shū)的前面1/3之一的內容寫(xiě)的還是不錯的,但是后面的東西就非?;逎⑶矣泻芏嗝黠@的文字錯誤??纯催@本書(shū)的翻譯者是好幾個(gè)人,估計每個(gè)人的翻譯能力不同造成了這本書(shū)的虎頭蛇尾。因此我不建議大家去買(mǎi)這本書(shū)作為圣經(jīng)收藏。這本書(shū)前半步的內容主要圍繞Posix的多線(xiàn)程,介紹的比較精彩的就是幾個(gè)多線(xiàn)程編程模型,把多線(xiàn)程的互斥和同步機制介紹的挺酣暢的,推薦一看。這些內容并非這本書(shū)首創(chuàng ),早在《UNIX網(wǎng)絡(luò )編程》第二卷進(jìn)程間通信就有了這些經(jīng)典的介紹,但是能系統的把這些機制結合到多線(xiàn)程編程中來(lái)還是有可圈可點(diǎn)之處的。此外畢竟《UNIX網(wǎng)絡(luò )編程》兩卷內容太老,書(shū)也太厚了,并不是大多數程序員所能坐下來(lái)細細看的。這里我還想表達一下對微軟在技術(shù)上的不足斥責。在 msdn中platform sdk部分中的windows多線(xiàn)程編程的內容真是簡(jiǎn)陋的可笑,只有傻兮兮的建立和退出線(xiàn)程的函數,關(guān)于互斥,條件的介紹一概全無(wú)。只能在它的 sample代碼中自己去找,sample代碼里面的線(xiàn)程同步方式居然是做一個(gè)死循環(huán)來(lái)死等,也不知道它把windows賣(mài)這么多錢(qián)是干什么吃的。 MFC中多線(xiàn)程的封裝倒是看上去像那么一回事情了,但是我想象不出在如此簡(jiǎn)陋的系統api上微軟到底是如何實(shí)現出MFC上線(xiàn)程功能的。擁護windows 的人不要在這里砸雞蛋,最好也能寫(xiě)一篇windows上的多線(xiàn)程介紹除了。這比砸雞蛋來(lái)得有意義多了。 好了,書(shū)歸正傳繼續說(shuō)Linux上的多線(xiàn)程。

在Linux 上,從內核角度而言,基本沒(méi)有什么線(xiàn)程和進(jìn)程的區別--大家都是進(jìn)程。一個(gè)進(jìn)程的多個(gè)線(xiàn)程只是多個(gè)特殊的進(jìn)程他們雖然有各自的進(jìn)程描述結構,卻共享了同一個(gè)代碼上下文。在Linux上,這樣的進(jìn)程稱(chēng)為輕量級進(jìn)程Light weight process。致此,就是關(guān)于線(xiàn)程的總體概念了,我們往往就在了解這個(gè)概念的情況下開(kāi)始我們的多線(xiàn)程編程之旅。這對于多線(xiàn)程編程入門(mén)已經(jīng)足夠了,然而事實(shí)上線(xiàn)程卻要復雜的多。首先多線(xiàn)程間的優(yōu)先級調度,內存資源(棧)分配和信號投遞就不是簡(jiǎn)單的共享同一個(gè)進(jìn)程代碼上下文所能所能解決的。其次,效率的問(wèn)題:如何有效的使用多 cpu資源(2.4內核的多線(xiàn)程就無(wú)法使用多個(gè)cpu,一個(gè)進(jìn)程的線(xiàn)程都被限制在同一個(gè)cpu上運行)。因此多線(xiàn)程庫Pthread的實(shí)現并不是一件簡(jiǎn)單的事情,它建立在特有的線(xiàn)程模型之上。

在Linux 2.4內核中, Linux內核中使用了一個(gè)內核線(xiàn)程來(lái)處理用戶(hù)態(tài)進(jìn)程中的多個(gè)線(xiàn)程的上下文切換(線(xiàn)程切換)。由于內核中并沒(méi)有什么線(xiàn)程組的概念,即一個(gè)進(jìn)程的多個(gè)線(xiàn)程,因此必須依靠在pthread庫中實(shí)現一個(gè)額外的線(xiàn)程來(lái)管理其他用戶(hù)線(xiàn)程(即用戶(hù)程序生成的線(xiàn)程)的建立,退出,資源分配和回收以及線(xiàn)程的切換。由于當時(shí)硬件并沒(méi)有線(xiàn)程寄存器之類(lèi)的冬冬來(lái)支持多線(xiàn)程,因此線(xiàn)程的切換性能和低下,并且需要引入復雜的機制在進(jìn)程的棧中為各個(gè)線(xiàn)程劃分出各自的棧數據所在位置,并且在切換時(shí)進(jìn)行棧數據拷貝。而最大的問(wèn)題是內核中缺乏對線(xiàn)程間的同步機制的支持,因此pthread庫不得不在底層依靠信號方式來(lái)實(shí)現同步,因此線(xiàn)程互斥中的互斥量操作和條件量操作都轉換為進(jìn)程的信號操作。pthread的實(shí)現中充斥了極其復雜的信號操作。大家都知道信號本身是低速的通信方式,因此勢必拖慢了線(xiàn)程的實(shí)際性能。最后的問(wèn)題就是信號處理,還有由于內核對線(xiàn)程的無(wú)知,必須由管理線(xiàn)程來(lái)接收信號后投遞給相應的線(xiàn)程,一方面是效率低,另外一方面由于信號產(chǎn)生的不確定性(比如讀取一個(gè)文件的時(shí)候突然出錯了),要準確投遞所有的信號給正確的線(xiàn)程難以保證。

而在IA-32硬件結構中,出現了對線(xiàn)程寄存器的支持,因此Pthread的線(xiàn)程上下文切換速度有了很大提高。但是由于硬件限制局限,線(xiàn)程的數量必須小于8192個(gè),反正我是覺(jué)得已經(jīng)很多了。

于是從2.5代碼開(kāi)始Linux內核采用了Native Posix Thread Library)方式。的設計思想初稿可參考nptl-design.pdf(http://people.redhat.com/drepper/nptl-design.pdf)

首先在IA-32和x86-64位體系結構上能實(shí)現任意數量的線(xiàn)程數量。通過(guò)引入了TLS系統調用可以建立多個(gè)GDT全局描述符表,每個(gè)cpu維護一個(gè)描述符表,每個(gè)表項存放一個(gè)線(xiàn)程。

其次,clone系統調用優(yōu)化了線(xiàn)程的建立和結束功能。也不再需要額外的調度線(xiàn)程的幫助就可以回收線(xiàn)程資源了。

其三,信號投遞由內核完成,而不再需要額外的用戶(hù)態(tài)管理線(xiàn)程的幫助,而嚴重錯誤信號之間結束整個(gè)進(jìn)程。

其四,引入了新的退出系統調用exit_group()。原來(lái)的exit保留用于退出單個(gè)線(xiàn)程,exit_group用于退出整個(gè)進(jìn)程。

其五, 新的exec調用會(huì )先結束到一個(gè)進(jìn)程中的所有線(xiàn)程后再載入新程序的執行,而不是只結束調用的線(xiàn)程。

其六,所有線(xiàn)程的資源使用情況(cpu資源,內存資源)會(huì )報告給整個(gè)進(jìn)程,而不再是只報告給初始化線(xiàn)程

其七,proc文件系統中只顯示初始化線(xiàn)程的信息,而不再是所有線(xiàn)程的信息(上萬(wàn)個(gè)線(xiàn)程會(huì )把proc文件系統拖死)

其八, 支持線(xiàn)程脫離, 執行Pthread_join的線(xiàn)程不需要再執行no wait。

其九,由內核來(lái)維護初始化線(xiàn)程(變成內核線(xiàn)程了),并在proc文件系統中顯示其狀態(tài),并維護直到所有線(xiàn)程退出來(lái)保證信號的投遞。

其十,內核支持無(wú)限制的線(xiàn)程數量。

最后,允許pthread_join在子線(xiàn)程已死之后返回,即pthread_join的返回和子線(xiàn)程狀態(tài)變成異步的了,提高了性能。

根據報告,中線(xiàn)程的啟動(dòng)和中止時(shí)間消耗只有Linuxthread的大約1/8,當線(xiàn)程數量急遽增加的時(shí)候,消耗時(shí)間的差異更加明顯。

在線(xiàn)程間同步試驗中,頻繁進(jìn)出臨界區的時(shí)間消耗只有原來(lái)的一半。

更多的用戶(hù)測試報告可以看 http://kerneltrap.org/node/422

至于如何在開(kāi)發(fā)中使用NPTL可參考Migrating to Linux kernel -- Part 5: Migrating apps to the kernel and NPTL(http://linuxdevices.com/articles/AT6753699732.html)。需要做的事情有這么幾件。

1:使用的內核的系統平臺

2:確定你的gcc支持NPTL

用# getconf GNU_LIBPTHREAD_VERSION命令來(lái)查看gcc的編譯時(shí)的對多線(xiàn)程的支持方式

如果返回的是linuxthreads-0.10,說(shuō)明你的gcc不支持NPTL

如果返回的是nptl-0.60這樣的信息,說(shuō)明你的gcc能用來(lái)編譯新的NPTL

3:重新在這樣的系統環(huán)境中編譯你的程序,不需要改變程序中對pthread的調用(但是某些函數被取消了)

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


關(guān)鍵詞: Linux NPTL 2.6 編程 線(xiàn)程

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>