linux 4.9 内核 nptl,【linuxThread和NPTL】
有關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是核心級線程嗎
當然是,不過它是在核外實現的,詳見四
【附】
POSIX Signals and Multithreaded Applications
The POSIX 1003.1 standard has some stringent requirements for signal handling of multithreaded applications:
Signal handlers must be shared among all threads of a multithreaded application; however, each thread must have its own mask of pending and blocked signals.
信號處理函數在所有線程間共享,但每個線程自己可以設定信號掩碼
The kill( ) and sigqueue( ) POSIX library functions?must send signals to whole multithreaded applications, not to a specific thread. The same holds for all signals (such as SIGCHLD, SIGINT, or SIGQUIT) generated by the kernel.
kill和sigqueue函數傳遞的應該是TGID(線程組id),接收者是該線程組中所有線程
Each signal sent to a multithreaded application will be delivered to just one thread, which is arbitrarily chosen by the kernel among the threads that are not blocking that signal.
送達線程組的信號應該只會被某一個線程接收,該線程由kernl從該線程組中未block該信號的所有線程中選定(arbitrarily),記住,只有一個,所以,在一個線程組中,只能有一個定時器。
If a fatal signal is sent to a multithreaded application, the kernel will kill all threads of the applicationnot just the thread to which the signal has been delivered.
致命錯誤發送給線程組。
總結
以上是生活随笔為你收集整理的linux 4.9 内核 nptl,【linuxThread和NPTL】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows下的dig 命令和nslo
- 下一篇: ffmpeg php linux,lin