NPTL的解釋

 

 

 並行技術
並行技術可分爲三類,分別是線程庫、消息傳遞庫和編譯器支持。線程庫(如 POSIX* 線程和 Windows* API 線程)可實現對線程的顯性控制;如果需要對線程進行精細管理,可以考慮使用這些顯性線程技術。藉助消息傳遞庫(如消息傳遞接口〔MPI〕),應用程序可同 時利用多臺計算機,它們彼此間不必共享同一內存空間。MPI 廣泛應用於科學計算領域。第三項技術是在編譯器中實現的線程處理支持,採用的形式自動並行化。一旦將線程處理引入到應用程序中,開發人員就可能要面對一系 列新的編程缺陷(Bug)。其中許多缺陷是難以檢測到的,需要付出額外的時間和關注以確保程序的正確運行。一些比較常見的線程處理問題包括:數據爭用 ,同步,線程停頓 ,死鎖 ,共享錯誤.
並行技術可以分爲多進程編程和多線程編程。人們總會用某種IPC(inter-process communication,進程間通信)的形式來實現進程間同步,如管道(pipes),信號量(semaphores),信息隊列(message queues),或者共享存儲(shared memory)。在所有的這些IPC形式中,共享存儲器是最快的(除了門(doors)之外)。在處理進程間資源管理,IPC和同步時,你可以選擇 POSIX或者System V的定義。
線程技術早在20世紀60年代就被提出,但真正應用多線程到操作系統中還是在20世紀80年代中期。現在,多線程技術已經被許多操作系統所支持,包括Windows NT/2000和Linux。
在1999年1月發佈的Linux 2.2內核中,進程是通過系統調用fork創建的,新的進程是原來進程的子進程。需要說明的是,在Linux 2.2.x中,不存在真正意義上的線程,Linux中常用的線程Pthread實際上是通過進程來模擬的。
也就是說,Linux中的線程也是通過fork創建的,是“輕”進程。Linux 2.2缺省只允許4096個進程/線程同時運行,而高端系統同時要服務上千的用戶,所以這顯然是一個問題。它一度是阻礙Linux進入企業級市場的一大因素。
2001年1月發佈的Linux 2.4內核消除了這個限制,並且允許在系統運行中動態調整進程數上限。因此,進程數現在只受制於物理內存的多少。在高端服務器上,即使只安裝了512MB內存,現在也能輕而易舉地同時支持1.6萬個進程。
在Linux 2.5內核中,已經做了很多改進線程性能的工作。在Linux 2.6中改進的線程模型仍然是由Ingo Molnar 來完成的。它基於一個1:1的線程模型(一個內核線程對應一個用戶線程),包括內核內在的對新NPTL(Native Posix Threading Library)的支持,這個新的NPTL是由Molnar和Ulrich Drepper合作開發的。
2003年12月發佈的Linux 2.6內核,對進程調度經過重新編寫,去掉了以前版本中效率不高的算法。進程標識號(PID)的數目也從3.2萬升到10億。內核內部的大改變之一就是Linux的線程框架被重寫,以使NPTL可以運行其上。
在現代操作系統裏,同一時間可能有多個內核執行流在執行,因此內核其實象多進程多線程編程一樣也需要一些同步機制來同步各執行單元對共享數據的訪 問。尤其是在多處理器系統上,更需要一些同步機制來同步不同處理器上的執行單元對共享的數據的訪問。在主流的Linux內核中包含了幾乎所有現代的操作系 統具有的同步機制,這些同步機制包括:原子操作、信號量(semaphore)、讀寫信號量(rw_semaphore)、spinlock、BKL (Big Kernel Lock)、rwlock、brlock(只包含在2.4內核中)、RCU(只包含在2.6內核中)和seqlock(只包含在2.6內核中)。
現在的隨着現在計算機體系結構的發展,指令級的並行和線程級的並行都在日新月異地發展着.

 

 

2.

2006 年 8 月 28 日

LinuxThreads 項目最初將多線程的概念引入了 Linux®,但是 LinuxThreads 並不遵守 POSIX 線程標準。儘管更新的 Native POSIX Thread Library(NPTL)庫填補了一些空白,但是這仍然存在一些問題。本文爲那些需要將自己的應用程序從 LinuxThreads 移植到 NPTL 上或者只是希望理解有何區別的開發人員介紹這兩種 Linux 線程模型之間的區別。

當 Linux 最初開發時,在內核中並不能真正支持線程。但是它的確可以通過 clone() 系統調用將進程作爲可調度的實體。這個調用創建了調用進程(calling process)的一個拷貝,這個拷貝與調用進程共享相同的地址空間。LinuxThreads 項目使用這個調用來完全在用戶空間模擬對線程的支持。不幸的是,這種方法有一些缺點,尤其是在信號處理、調度和進程間同步原語方面都存在問題。另外,這個 線程模型也不符合 POSIX 的要求。

要改進 LinuxThreads,非常明顯我們需要內核的支持,並且需要重寫線程庫。有兩個相互競爭的項目開始來滿足這些要求。一個包括 IBM 的開發人員的團隊開展了 NGPT(Next-Generation POSIX Threads)項目。同時,Red Hat 的一些開發人員開展了 NPTL 項目。NGPT 在 2003 年中期被放棄了,把這個領域完全留給了 NPTL。

儘管從 LinuxThreads 到 NPTL 看起來似乎是一個必然的過程,但是如果您正在爲一個歷史悠久的 Linux 發行版維護一些應用程序,並且計劃很快就要進行升級,那麼如何遷移到 NPTL 上就會變成整個移植過程中重要的一個部分。另外,我們可能會希望瞭解二者之間的區別,這樣就可以對自己的應用程序進行設計,使其能夠更好地利用這兩種技 術。

本文詳細介紹了這些線程模型分別是在哪些發行版上實現的。

LinuxThreads 設計細節

線程 將應用程序劃分成一個或多個同時運行的任務。線程與傳統的多任務進程 之間的區別在於:線程共享的是單個進程的狀態信息,並會直接共享內存和其他資源。同一個進程中線程之間的上下文切換通常要比進程之間的上下文切換速度更 快。因此,多線程程序的優點就是它可以比多進程應用程序的執行速度更快。另外,使用線程我們可以實現並行處理。這些相對於基於進程的方法所具有的優點推動 了 LinuxThreads 的實現。

LinuxThreads 最初的設計相信相關進程之間的上下文切換速度很快,因此每個內核線程足以處理很多相關的用戶級線程。這就導致了一對一 線程模型的革命。

讓我們來回顧一下 LinuxThreads 設計細節的一些基本理念:

  • LinuxThreads 非常出名的一個特性就是管理線程(manager thread)。管理線程可以滿足以下要求:

    • 系統必須能夠響應終止信號並殺死整個進程。
    • 以堆棧形式使用的內存回收必須在線程完成之後進行。因此,線程無法自行完成這個過程。
    • 終止線程必須進行等待,這樣它們纔不會進入殭屍狀態。
    • 線程本地數據的回收需要對所有線程進行遍歷;這必須由管理線程來進行。
    • 如果主線程需要調用 pthread_exit(),那麼這個線程就無法結束。主線程要進入睡眠狀態,而管理線程的工作就是在所有線程都被殺死之後來喚醒這個主線程。
  • 爲了維護線程本地數據和內存,LinuxThreads 使用了進程地址空間的高位內存(就在堆棧地址之下)。
  • 原語的同步是使用信號 來實現的。例如,線程會一直阻塞,直到被信號喚醒爲止。
  • 在克隆系統的最初設計之下,LinuxThreads 將每個線程都是作爲一個具有惟一進程 ID 的進程實現的。
  • 終止信號可以殺死所有的線程。LinuxThreads 接收到終止信號之後,管理線程就會使用相同的信號殺死所有其他線程(進程)。
  • 根據 LinuxThreads 的設計,如果一個異步信號被髮送了,那麼管理線程就會將這個信號發送給一個線程。如果這個線程現在阻塞了這個信號,那麼這個信號也就會被掛起。這是因爲管理線程無法將這個信號發送給進程;相反,每個線程都是作爲一個進程在執行。
  • 線程之間的調度是由內核調度器來處理的。

 

發佈了21 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章