1. 程式人生 > >介紹NPTL (經典--詮釋了執行緒的概念,以及linux排程單位)

介紹NPTL (經典--詮釋了執行緒的概念,以及linux排程單位)

               

POSIX Thread Library (NPTL)使Linux核心可以非常有效的執行使用POSIX執行緒標準寫的程式。這裡有一個測試資料,在32位機下,NPTL成功啟動100000個執行緒只用了2秒,而不使用NPTL將需要大約15分鐘左右的時間。

歷史

在核心2.6以前的排程實體都是程序,核心並沒有真正支援執行緒。它是能過一個系統呼叫clone()來實現的,這個呼叫建立了一份呼叫程序的拷貝,跟fork()不同的是,這份程序拷貝完全共享了呼叫程序的地址空間。LinuxThread就是通過這個系統呼叫來提供執行緒在核心級的支援的(許多以前的執行緒實現都完全是在使用者態,核心根本不知道執行緒的存在)。非常不幸的是,這種方法有相當多的地方沒有遵循POSIX標準,特別是在訊號處理,排程,程序間通訊原語等方面。

很顯然,為了改進LinuxThread必須得到核心的支援,並且需要重寫執行緒庫。為了實現這個需求,開始有兩個相互競爭的專案:IBM啟動的NGTP(Next Generation POSIX Threads)專案,以及Redhat公司的NPTL。在2003年的年中,IBM放棄了NGTP,也就是大約那時,Redhat釋出了最初的NPTL。

NPTL最開始在redhat linux 9裡釋出,現在從RHEL3起核心2.6起都支援NPTL,並且完全成了GNU C庫的一部分。

設計

NPTL使用了跟LinuxThread相同的辦法,在核心裡面執行緒仍然被當作是一個程序,並且仍然使用了clone()系統呼叫(在NPTL庫裡呼叫)。但是,NPTL需要核心級的特殊支援來實現,比如需要掛起然後再喚醒執行緒的執行緒同步原語futex.

NPTL也是一個1*1的執行緒庫,就是說,當你使用pthread_create()呼叫建立一個執行緒後,在核心裡就相應建立了一個排程實體,在linux裡就是一個新程序,這個方法最大可能的簡化了執行緒的實現。

除NPTL的1*1模型外還有一個m*n模型,通常這種模型的使用者執行緒數會比核心的排程實體多。在這種實現裡,執行緒庫本身必須去處理可能存在的排程,這樣線上程庫內部的上下文切換通常都會相當的快,因為它避免了系統呼叫轉到核心態。然而這種模型增加了執行緒實現的複雜性,並可能出現諸如優先順序反轉的問題,此外,使用者態的排程如何跟核心態的排程進行協調也是很難讓人滿意。

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

有一個問題一直沒有想清楚,請教牛人,謝謝。資源描述:        系統環境:4個CPU, linux2.6核心,NPTL,SMP。        問題:        (程序是資源單元;執行緒是執行單元。)        一個程序擁有4個執行緒,這4個執行緒同時在4個CPU上執行。        問1:系統的排程單位是程序還是執行緒呢?(針對linux2.6核心);        問2:如果排程單位是執行緒,每個執行緒都應該執行在同一個程序的上下文中,如果這樣的話就需要對程序上下文加鎖;同時如果有其他程序的執行緒也執行在同一個CPU上,那麼程序的上下文切換會非常頻繁?             如果排程單位是程序,又沒有辦法解釋同一個程序中的4個執行緒同時跑在4個CPU上?        問3:看到一篇文章說“SMP的負載均衡是按程序數計算的”不知道是否正確。             如果正確,同一個程序的所有執行緒應該分配到同一個CPU上,不解?

答:

問題1:    linux核心中的排程單位總是一個程序。但是核心中有對執行緒的支援。問題2:    既然在linux的執行緒就是一個程序.就不存在什麼所有執行緒都在同一程序上下文。而且這個觀點是錯誤的。一個執行緒是什麼?執行緒只是一個程序的子集。也就是說是一個程序上下文的子集。而且每個執行緒的上下文的很少有交集。除非兩個執行緒之間需要通訊。linux中程序所傳建的執行緒本質就是程序。只不過這些子程序和父程序看到的都是同一地址空間,共享資源。 恢復一個執行緒的執行只需要恢復執行緒上下文。既然是執行緒在執行,何來程序上下文? 執行緒的實現方式不同.但原理本質一樣。 既然linux的排程單位是程序,而執行緒又是以程序實現的.所以程序的四個執行緒在4個CPU上同時執行是可能的.只要不存在互斥。問題3:    這個是高階問題... 不清楚...樓主可以goolge下.應該很多文章和論文的。