1. 幾個概念

1.1 併發

在作業系統的一個時間段中,有幾個程式同時處於啟動執行到執行完畢之間的狀態,且這幾個程式都在同一個處理機上執行。

併發又有偽併發和真併發:偽併發是指單核處理器的併發,真併發是指多核處理器的併發。

1.2 互斥

併發程序之間的制約關係有兩種,即互斥和同步。

多個併發程序之間,因競爭使用臨界資源而互相排斥執行的間接制約關係,叫作互斥。

例1:

這裡寫圖片描述

例2:共享變數

設兩個程序P1,P2,它們共享同一變數count,主要操作如下:

程序P1 程序P2
R1:= count R2:= count
R1:= R1+1 R2:= R2+1
count:= R1 count:= R2

其中,R1和R2是處理機的兩個通用暫存器。它們可以按各自獨立的速度前進,所以執行的順序也可能是:

程序 執行
程序P1: R1:= count
程序P2: R2:= count
程序P1: R1:= R1+1;count:= R1
程序P2: R2:= R2+1;count:= R2

1.3 同步

在某些地方,多個併發程序需要相互等待或交換資訊而產生的直接制約關係,叫做同步。

併發程序之間不是相互排斥臨界資源,而是相互依賴的關係。進一步地說,同步關係就是前一個程序的輸出作為後一個程序的輸入;當第一個程序沒有輸出時,第二個程序必須等待。具有同步關係的一組併發程序,相互發送的資訊稱為訊息或事件。

下面是一個司機和售票員同步的例子:

這裡寫圖片描述

還有一個協作程序的例子:

使用者作業程式的形式:Z=func1(x)func2(y),其中func1(x),func2(y)均是一個複雜函式,為了加速計算,按以下方法計算:

  • 程序P1、P2分別計算func1(x)func2(y)

  • 程序P1與P2計算結果相乘,獲得結果Z

這裡寫圖片描述

1.4 並行

在單核處理器的多道程式環境中,程序被交替執行,表現出一種併發的外部特徵;在多核處理器的多道程式環境中,程序不僅可以交替執行,還可以重疊執行,即並行。

在多核處理器上,程式才可以實現並行處理。從而可知,並行是針對多核處理器而言。並行是同一時刻發生多個事件,具有併發的含義;但併發不一定並行,即併發事件之間不一定要同一時刻發生。

1.5 多執行緒

多執行緒是程式設計的邏輯層概念,它是程序中併發執行的一段程式碼。多執行緒可以實現執行緒間的切換執行。

1.6 非同步

非同步與同步是相對的:同步是順序執行程序,執行完一個程序再執行下一個程序,需要程序之間等待、協調執行;非同步是程序之間彼此獨立,在等待其他程序的執行時,本程序繼續做自己的事,不需要等待其他程序完成後再工作。

在多道程式環境下,程序以非同步方式併發執行。

非同步與多執行緒不是同等關係:非同步是最終目的,多執行緒只是我們實現非同步的一種方式。非同步是讓呼叫方法的主執行緒不用同步等待另一執行緒的完成,主執行緒可以同時做其它事情。

實現非同步可以採用多執行緒技術或者交給另外的程序處理。

2. 事例理解

為了對以上概念更好地理解,舉一個簡單例子,假設我們要做燒開水,舉槓鈴100下, 洗衣服這3件事情。

  • 燒開水:準備燒開水(1分鐘), 等開水燒開(8分鐘) , 關掉燒水機(1分鐘)

  • 舉槓鈴100下:舉槓鈴100下(10分鐘)

  • 洗衣服:準備洗衣服(1分鐘), 等衣服洗完(5分鐘),關掉洗衣機(1分鐘)

2.1 單核處理器

  • 同步執行

事情步驟安排:燒水:準備燒開水(1分鐘), 等開水燒開(8分鐘) , 關掉燒水機(1分鐘);舉槓鈴100下:舉槓鈴100下(10分鐘);洗衣服:準備洗衣服(1分鐘), 等衣服洗完(5分鐘),關掉洗衣機(1分鐘)

做完3件事,花費的時間t = 1+ 8 +1 + 10 + 1+ 5 +1 = 27(分鐘)

  • 非同步並行

在等待事情執行時,我(單核)可以切換出去,做別的事情。

事情步驟安排:準備燒開水(1分鐘) + 準備洗衣服(1分鐘) + 舉50下槓鈴 (5分鐘)+ 關洗衣機(1分鐘) + 舉槓鈴20下(2分鐘)+ 關燒水機(1分鐘) + 舉30下槓鈴(3分鐘)

在等待衣服洗完(5分鐘)時,我(單核)執行舉50下槓鈴(5分鐘);在等待水燒開(8分鐘)時,我(單核)執行舉50下槓鈴 (5分鐘)+ 關洗衣機(1分鐘) + 舉槓鈴20下(2分鐘)。

做完3件事,花費的時間t = 1 + 1 + 5 + 1 + 2 + 1 + 3 = 14(分鐘)

2.2 雙核處理器

  • 非同步並行

核1:準備燒開水(1分鐘)+ 舉槓鈴50下(5分鐘)+ 等待(3分鐘)+ 關掉燒水機 (1分鐘)

核2:準備洗衣服(1分鐘)+ 舉槓鈴50下(5分鐘)+ 關掉洗衣機(1分鐘) + 等待(3分鐘)

其中,在等待水燒開(8分鐘)時,核1執行舉槓鈴50下(5分鐘),等待(3分鐘);在等待衣服洗完(5分鐘)時,核2執行舉槓鈴50下(5分鐘)。

做完3件事,花費的時間t = 1 + 5 + 3 + 1 = 10(分鐘),其中雙核都等待了3分鐘。

  • 非同步非並行

核1:舉槓鈴100下(10分鐘)

核2:準備燒開水(1分鐘)+ 準備洗衣服(1分鐘)+ 等待(6分鐘)+ 關掉燒水機(1分鐘)+ 關掉洗衣機(1分鐘)

其中,在等待水燒開(8分鐘)時,核2執行準備燒開水(1分鐘),準備洗衣服(1分鐘),等待(6分鐘);在等待衣服洗完(5分鐘)時,核2執行等待(6分鐘)。

做完3件事,花費的時間t =1 + 1 + 6 + 1 + 1 = 10(分鐘)

2.3 多執行緒

  • 單核處理器

執行緒1:準備燒開水(1分鐘), 等水燒開(8分鐘) , 關掉燒水機(1分鐘)

執行緒2:舉槓鈴100下(10分鐘)

執行緒3:準備洗衣服(1分鐘), 等水燒開(5 分鐘) , 關掉洗衣機(1分鐘)

CPU最理想的切換方式:

執行緒1:準備燒開水(1分鐘)+ sleep 1 + sleep 5 + sleep 1 + sleep 2 + 關開水(1分鐘)

執行緒2:sleep 1+ sleep 1 + 舉槓鈴50(5分鐘)+ sleep 1 + 舉槓鈴20(2分鐘)+ sleep1 + 舉槓鈴30下(3分鐘)

執行緒3:sleep 1 + 準備洗衣服(1分鐘)+ sleep 5 +關洗衣機(1分鐘)

最後使用了14分鐘,與非同步是一樣的。但實際上是不一樣的,因為執行緒不會按照我們設想的去跑。如果執行緒2舉槓鈴先跑,整個流程的速度就下來了。

2.4 非同步和同步,多執行緒與非同步,單核與多核的不同

非同步和同步的區別:在IO等待時,同步不會切走,等待浪費了時間。

多執行緒比較容易地實現了非同步切換的思想, 因為多執行緒較容易寫。多執行緒本身還是以同步完成,但是比不上非同步的效率。

多核的好處,就是可以同時做事情, 這個與單核不一樣。如果都是獨佔CPU的作業,比如舉槓鈴。在單核情況下,多執行緒和單執行緒沒有區別。

3. 參考文章