天天看點

重學作業系統原理系列 - 程序管理(一)六、線程

六、線程

6.1 線程的引入

引入理由

  • 應用的需要
  • 開銷的考慮
  • 性能的考慮

6.1.1 應用的需要

我們看一個例子,一個

web

伺服器的工作方式

  • 從用戶端接收網頁請求
  • 從磁盤上檢索相關的網頁,讀入記憶體(此時程序是停止的,直到讀取完畢)
  • 将網頁傳回給對應的用戶端

可以看到每次從磁盤讀取的時候程序都是暫停的,這樣會導緻性能低下

那如何提高伺服器的工作效率?通常情況下是使用網頁緩存

沒有線程情況下的兩種解決方案

  • 一個服務程序undefined這種情況下也是一種順序程式設計,雖然采用了緩存機制,但是性能同樣不高。而如果設定多個程序,這多個程序之間又是互相獨立的,有獨立的位址空間,是以不能共享資訊
  • 有限狀态機undefined這種方式程式設計模型複雜,采用非阻塞的

    I/O

多線程的解決方式

重學作業系統原理系列 - 程式管理(一)六、線程

**說明:**這是一個多線程的

web

伺服器的工作方式,首先讀取用戶端的請求,之後由分派線程将各個任務分派給工作線程,這裡還是采用了網頁緩存

于是我們可以看到一個

web

伺服器的實作有三種方式:

重學作業系統原理系列 - 程式管理(一)六、線程

6.1.2 開銷的考慮

重學作業系統原理系列 - 程式管理(一)六、線程

6.1.3 性能的考慮

如果有多個處理器的話,一個程序就會有多個線程同時在執行了,這樣可以極大的提高運作性能

6.2 線程的基本概念

重學作業系統原理系列 - 程式管理(一)六、線程

線程的屬性

  • 有辨別符

    ID

  • 有狀态及狀态轉換

    -->

    需要提供一些操作
  • 不運作時需要儲存的上下文(程式計數器等寄存器)
  • 有自己的棧和棧指針
  • 共享所在程序的位址空間和其他資源
  • 建立、撤銷另一個線程(程式開始是以一個單線程方式運作的)

6.3 線程機制的實作

一般有三種實作機制

  • 使用者級線程
  • 核心級線程
  • 混合(兩者結合)方法6.3.1 使用者級線程
重學作業系統原理系列 - 程式管理(一)六、線程

說明:線程是由運作時系統管理的,在核心中隻有程序表。典型例子就是

UNIX

undefinedPOSIX線程庫–PTHREAD

重學作業系統原理系列 - 程式管理(一)六、線程

優點

  • 線程切換快
  • 排程算法是應用程式特定的
  • 使用者級線程可運作在任何作業系統上(隻需要實作線程庫)

缺點

  • 核心隻将處理器配置設定給程序,同一程序中的兩個線程不能同時運作于兩個處理器上
  • 大多數系統調用是阻塞的,是以,由于核心阻塞程序,故程序中所有線程也被阻塞。(可以在調用之前判斷進行解決,如果是阻塞線程,那麼就換其他線程)6.3.2 核心級線程
重學作業系統原理系列 - 程式管理(一)六、線程
  • 線程建立在使用者空間完成
  • 線程排程等在核心态完成
  • 例子如

    Solaris

    作業系統

6.4 線程狀态(Java)

0)建立:建立後尚未啟動的線程處于這種狀态。

1)運作:包括了 OS 中 Running 和 Ready 狀态,也就是處于此狀态的線程可能正在運作,也可能正在等待 cpu 為它配置設定執行時間

2)無限期等待:處于這種狀态的線程不會被配置設定 cpu 執行時間,要等待其他線程顯示喚醒。以下方法會讓線程進入無限期等待 :

  • 沒有設定 timeout 的 object.wait()
  • 沒有設定 timeout 參數的 Thread.join()
  • LockSupport.park()

3)有限期的等待:處于這種狀态的線程也不會被配置設定 cpu 執行時間,不過無需等待被其他線程顯示喚醒,而是在一定時間後,他們會由 OS 自動喚醒 1.設定了 timeout 的 object.wait() 方法 2. 設定了 timeout 參數的 Thread.join() 3.LockSupport.parkNanos()

4.LockSupport.parkUnit()

4) 阻塞:與"等待"的差別:

  • 阻塞态在等待擷取一個排它鎖,這個事件将在另外一個線程放棄這個鎖的時候發生
  • 等待狀态在等待一段時間或者喚醒動作。

5)結束:已終止線程的線程狀态,線程已經結束執行。 程序的通信類型

  • 共享存儲器、管道、客戶機-伺服器系統(socket)
  • 直接通信、間接通信(信箱)