有關linux執行緒的問題,有幾個需要澄清的:
1.核心級執行緒與使用者級執行緒
2.核內還是核外
3.linux的標準執行緒庫是哪個?他們之間有什麼區別?
4.lwp與執行緒的關係
5.linuxthreads的缺點,nptl作了哪些改善?
6.如何確定你的gcc支援nptl
7.最後弱弱地問一句,linuxthread是核心級執行緒嗎
以下是我的看法,不全
一.核心級執行緒與使用者級執行緒
從程序演化出執行緒,最主要的目的就是更好的支援smp以及減小(程序/程序)上下文切換開銷。
針對執行緒模型的兩大意義,分別開發出了核心級執行緒和使用者級執行緒兩種執行緒模型,分類的標準主要是執行緒的排程者在核內還是在核外。前者更利於併發使用多處理器的資源,而後者則更多考慮的是上下文切換開銷。
二.核內還是核外
核內實現的執行緒自然是核心級執行緒;
核外實現的執行緒可能是核心級執行緒,也可能是使用者級;
例如:在核外實現的執行緒可以分為"一對一"、"多對一"兩種模型,前者用乙個核心程序(也許是輕量程序)對應乙個執行緒,將執行緒排程等同於程序排程,交給核心完成(所以,它是乙個核心級執行緒),而後者則完全在核外實現多執行緒,排程也在使用者態完成(它是使用者級執行緒)。
三.linux的標準執行緒庫是哪個?他們之間有什麼區別?
linuxthreads、ngpt、nptl
其中,linuxthreads是2.5之前linux採用的標準thread庫,ngpt為m:n模型,而nptl是2.5以後的標準thread庫,整合在glibc中。
四.lwp與執行緒的關係
linux核心在 2.0.x版本就已經實現了輕量程序,應用程式可以通過乙個統一的clone()系統呼叫介面,用不同的引數指定建立輕量程序還是普通程序。
針對linuxthreads、nptl:
它所實現的就是基於核心輕量級程序的"一對一"執行緒模型,乙個執行緒實體對應乙個核心輕量級程序,執行緒的排程等同於lwp的排程(核內排程,所以是核心級執行緒),而執行緒之間的管理在核外函式庫中實現。
五.linuxthreads的缺點,nptl作了哪些改善?
linuxthread的缺點:
1.程序id問題
按照posix定義,同一程序的所有執行緒應該共享乙個程序id和父程序id,但是目前"一對一"模型,導致每個執行緒都有自己的程序id
2.訊號處理問題
由於非同步訊號是核心以程序為單位分發的,而linuxthreads的每個執行緒對核心來說都是乙個程序,且沒有實現"執行緒組",因此,某些語義不符合posix標準,比如沒有實現向程序中所有執行緒傳送訊號
3.執行緒總數問題
4.管理執行緒問題
管理執行緒容易成為瓶頸,這是這種結構的通病;同時,管理執行緒又負責使用者執行緒的清理工作,因此,儘管管理執行緒已經遮蔽了大部分的訊號,但一旦管理執行緒死亡,使用者執行緒就不得不手工清理了,而且使用者執行緒並不知道管理執行緒的狀態,之後的執行緒建立等請求將無人處理。
5.同步問題
linuxthreads中的執行緒同步很大程度上是建立在訊號基礎上的,這種通過核心複雜的訊號處理機制的同步方式,效率一直是個問題
nptl:
1.程序id
引入thread group的概念,
process id-對每乙個程序或者執行緒,都有乙個獨一無二的pid,
thread group id-對於程序,tgid=pid; 對於執行緒,tgid=parent pid;
tid-對每乙個執行緒,都有乙個獨一無二的執行緒id;
getpid-返回的是tgid;
通過這樣乙個方法,滿足了程序id的要求
2.訊號處理問題
見【附】
六.如何確定你的gcc支援nptl
getconf gnu_libpthread_version命令來檢視gcc的編譯時的對多執行緒的支援方式
如果返回的是linuxthreads-0.10,說明你的gcc不支援nptl
如果返回的是nptl-0.60這樣的資訊,說明你的gcc能用來編譯新的nptl
七.最後弱弱地問一句,linuxthread是核心級執行緒嗎
當然是,不過它是在核外實現的,詳見四
【附】訊號處理函式在所有執行緒間共享,但每個執行緒自己可以設定訊號掩碼
the kill( ) and sigqueue( ) posix library functions
kill和sigqueue函式傳遞的應該是tgid(執行緒組id),接收者是該執行緒組中所有執行緒
送達執行緒組的訊號應該只會被某乙個執行緒接收,該執行緒由kernl從該執行緒組中未block該訊號的所有執行緒中選定(arbitrarily),記住,只有乙個,所以,在乙個執行緒組中,只能有乙個定時器。
致命錯誤傳送給執行緒組。
幾個有關STL vector的問題
1,使用iterator進行遍歷和直接使用下標遍歷的區別 for vector iterator it v.begin it v.end it for int i 0 i2,如何判斷乙個vector是空的 vectorv1 v1.empty 則是返回乙個布林型變數 3,vector中元素的插入 在p...
有關DLL的幾個問題
一 dll被多個程序呼叫問題 win32系統會確保記憶體中只有乙個該dll的拷貝,這是通過記憶體對映檔案來實現的。不同的程序分別將這份dll的 段位址對映到自己的程序空間中,同時不同的程序在自己的程序空間分別有各自的乙份該dll的資料段拷貝。這是因為,在win32環境中,每個程序都有了它自己的位址空...
有關c 的幾個問題
1.在物件導向中既然結構體中可以有成員變數也可以有方法等,那為什麼還要有類的存在呢?結構體是值型別,而類是引用型別。然後就是值型別和引用型別之間的區別了。2.string 和 string 有何區別?通過typeof 的測試可以發現兩者的結果都是 system.string 型別。其實 string...