程式與執行緒概念、區別、以及執行緒間的通訊
概念
- 程式是對程式執行時的封裝,是作業系統分配資源的基本單位,實現作業系統的併發。
- 執行緒是程式的子單位,是CPU排程和分派的基本單位,實現程式內部的併發。是OS識別的最小執行與排程單位,每個執行緒獨佔一個虛擬處理器,每個執行緒完成不同的任務,但共相一個地址空間。
區別
- 程式在執行過程中擁有獨立的記憶體單元,而多個執行緒共享程式的記憶體。(每個執行緒擁有自己的棧段,來儲存所有區域性變數和零時變數)
- 程式是資源分配的最小單位,執行緒是CPU排程的最小單位;
程式間的通訊
程式間通訊主要包括管道、系統IPC(包括訊息佇列、訊號量、訊號、共享記憶體等)、以及套接字socket。
- 管道
匿名和命名兩種,用於父子程式通訊,命名管道還允許不同程式間的通訊。
=>匿名管道:半雙工,只允許資料往一個方向流動,只能用於父子程式之間的通訊,
命名管道FIFO:可在無關的通道間交換資料 - 系統IPC
2.1 訊息佇列,
2.2 訊號量,它是一個計數器,用來控制多個程式對共享資源的訪問,訊號量用於程式間的互斥與同步,不儲存程式間的通訊資料。
而訊號是用於通知接收程式某個時間已經發生。
2.3 共享記憶體
它使得多個程式可以訪問同一塊記憶體空間,不同程式可以及時看到對方程式中對共享記憶體中資料得更新。這種方式需要依靠某種同步操作,如互斥鎖和訊號量等
特點:
共享記憶體是最快的一種IPC,因為程式是直接對記憶體進行存取
因為多個程式可以同時操作,所以需要進行同步
訊號量+共享記憶體通常結合在一起使用,訊號量用來同步對共享記憶體的訪問
3.套接字SOCKET:
socket也是一種程式間通訊機制,與其他通訊機制不同的是,它可用於不同主機之間的程式通訊。
執行緒間的通訊方式
臨界區:透過多執行緒的序列化來訪問公共資源或一段程式碼,速度快,適合控制資料訪問;
互斥量Synchronized/Lock:採用互斥物件機制,只有擁有互斥物件的執行緒才有訪問公共資源的許可權。因為互斥物件只有一個,所以可以保證公共資源不會被多個執行緒同時訪問
訊號量Semphare:為控制具有有限數量的使用者資源而設計的,它允許多個執行緒在同一時刻去訪問同一個資源,但一般需要限制同一時刻訪問此資源的最大執行緒數目。
事件(訊號),Wait/Notify:透過通知操作的方式來保持多執行緒同步,還可以方便的實現多執行緒優先順序的比較操作程式間通訊的方式:
理解多執行緒程式是如何執行程式碼
只有理解多執行緒程式是如何執行程式碼的,才能處理如何保證互斥、保證同步和死鎖問題,記住執行緒就是輕量級程式
一個CPU兩個執行緒,怎麼執行
- 每個執行緒是獨佔CPU資源進行運算和執行,從兩個執行緒來看,是交替執行。兩個執行緒併發執行,獨佔CPU一小會。
- 兩個執行緒是被作業系統使用 排程演算法 進行排程,獲取到CPU。例如現在的時間片輪轉,之前的先來先服務、短作業優先,優先順序優先等等
- 兩個執行緒是搶佔式執行的,誰先執行誰後執行是說不清楚的。有可能是主執行緒後續先執行,也有可能是工作執行緒先執行。
兩個CPU兩個執行緒,怎麼執行
- 各自佔一個CPU,兩個執行緒同行執行,並行執行
2個CPU4個執行緒,怎麼執行(接近現實計算機執行情況)
1.CPU少於執行緒數,作業系統必須使用 排程演算法,讓每一個執行緒都獲取到CPU資源,得以讓執行緒都能向下推進,執行各自的程式碼
2.在當前這種情況下,存在並行(多個CPU執行多個執行緒,同時間執行)也存在併發(一個CPU執行多個執行緒,交替執行)。
4.對於程式猿而言,針對多執行緒程式,一定要有 “並行”思維。 這樣才能學好多執行緒
3.現在的作業系統就是這種情況,程式/執行緒數量遠遠大於CPU的核數,所以,需要作業系統排程。那麼就形成了並行或者併發
執行緒是如何切換的
執行緒的結構:
當執行緒要切換時,執行緒的task_struct裡面的 PC指標會(程式計數器)儲存 這個執行緒的彙編程式中將要執行的下一條指令;
那麼恢復的時候又是從哪裡恢復的:執行緒的task_struct中上下文資訊中恢復,保CPU存暫存器當中的值。