文章目錄
操作系統
進程與線程
對於有線程系統:
- 進程是資源分配的獨立單位
- 線程是資源調度的獨立單位
對於無線程系統:
進程是資源調度、分配的獨立單位
進程之間的通信方式以及優缺點
管道(PIPE)
-
有名管道:一種半雙工的通信方式,它允許無親緣關係進程間的通信
- 優點:可以實現任意關係的進程間的通信
- 缺點:
- 長期存於系統中,使用不當容易出錯
- 緩衝區有限
-
無名管道:一種半雙工的通信方式,只能在具有親緣關係的進程間使用(父子進程)
- 優點:簡單方便
- 缺點:
- 侷限於單向通信
- 只能創建在它的進程以及其有親緣關係的進程之間
- 緩衝區有限
信號量(Semaphore): 一個計數器,可以用來控制多個線程對共享資源的訪問
- 優點:可以同步進程
- 缺點:信號量有限
信號(Signal): 一種比較複雜的通信方式,用於通知接收進程某個事件已經發生
消息隊列(Message Queue): 是消息的鏈表,存放在內核中並由消息隊列標識符標識
- 優點:可以實現任意進程間的通信,並通過系統調用函數來實現消息發送和接收之間的同步,無需考慮同步問題,方便
- 缺點:信息的複製需要額外消耗 CPU 的時間,不適宜於信息量大或操作頻繁的場合
共享內存(Shared Memory): 映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問
- 優點:無須複製,快捷,信息量大
- 缺點:
- 通信是通過將共享空間緩衝區直接附加到進程的虛擬地址空間中來實現的,因此進程間的讀寫操作的同步問題
- 利用內存緩衝區直接交換信息,內存的實體存在於計算機中,只能同一個計算機系統中的諸多進程共享,不方便網絡通信
套接字(Socket): 可用於不同及其間的進程通信
- 優點:
- 傳輸數據爲字節級,傳輸數據可自定義,數據量小效率高
- 傳輸數據時間短,性能高
- 適合於客戶端和服務器端之間信息實時交互
- 可以加密,數據安全性強
- 缺點:需對傳輸的數據進行解析,轉化成應用級的數據。
線程之間的通信方式
鎖機制: 包括互斥鎖/量(mutex)、讀寫鎖(reader-writer lock)、自旋鎖(spin lock)、條件變量(condition)
- 互斥鎖/量(mutex):提供了以排他方式防止數據結構被併發修改的方法。
- 讀寫鎖(reader-writer lock):允許多個線程同時讀共享數據,而對寫操作是互斥的。
- 自旋鎖(spin lock)與互斥鎖類似,都是爲了保護共享資源。互斥鎖是當資源被佔用,申請者進入睡眠狀態;而自旋鎖則循環檢測保持着是否已經釋放鎖。
- 條件變量(condition):可以以原子的方式阻塞進程,直到某個特定條件爲真爲止。對條件的測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一起使用。
信號量機制(Semaphore)
- 無名線程信號量
- 命名線程信號量
信號機制(Signal): 類似進程間的信號處理
屏障(barrier): 屏障允許每個線程等待,直到所有的合作線程都達到某一點,然後從該點繼續執行。
線程間的通信目的主要是用於線程同步,所以線程沒有像進程通信中的用於數據交換的通信機制
進程之間的通信方式以及優缺點來源於:進程線程面試題總結
進程之間私有和共享的資源
- 私有:地址空間、堆、全局變量、棧、寄存器
- 共享:代碼段,公共數據,進程目錄,進程 ID
對比
對比維度 | 多進程 | 多線程 | 總結 |
---|---|---|---|
數據共享、同步 | 數據共享複雜,需要用 IPC;數據是分開的,同步簡單 | 因爲共享進程數據,數據共享簡單,但也是因爲這個原因導致同步複雜 | 各有優勢 |
內存、CPU | 佔用內存多,切換複雜,CPU 利用率低 | 佔用內存少,切換簡單,CPU 利用率高 | 線程佔優 |
創建銷燬、切換 | 創建銷燬、切換複雜,速度慢 | 創建銷燬、切換簡單,速度很快 | 線程佔優 |
編程、調試 | 編程簡單,調試簡單 | 編程複雜,調試複雜 | 進程佔優 |
可靠性 | 進程間不會互相影響 | 一個線程掛掉將導致整個進程掛掉 | 進程佔優 |
分佈式 | 適應於多核、多機分佈式;如果一臺機器不夠,擴展到多臺機器比較簡單 | 適應於多核分佈式 | 進程佔優 |
對比
優劣 | 多進程 | 多線程 |
---|---|---|
優點 | 編程、調試簡單,可靠性較高 | 創建、銷燬、切換速度快,內存、資源佔用小 |
缺點 | 創建、銷燬、切換速度慢,內存、資源佔用大 | 編程、調試複雜,可靠性較差 |
選擇
- 需要頻繁創建銷燬的優先用線程
- 需要進行大量計算的優先使用線程
- 強相關的處理用線程,弱相關的處理用進程
- 可能要擴展到多機分佈的用進程,多核分佈的用線程
- 都滿足需求的情況下,用你最熟悉、最拿手的方式
多進程與多線程間的對比、優劣與選擇來自:多線程還是多進程的選擇及區別
Linux 內核的同步方式
原因
在現代操作系統裏,同一時間可能有多個內核執行流在執行,因此內核其實象多進程多線程編程一樣也需要一些同步機制來同步各執行單元對共享數據的訪問。尤其是在多處理器系統上,更需要一些同步機制來同步不同處理器上的執行單元對共享的數據的訪問。
同步方式
- 原子操作
- 信號量(semaphore)
- 讀寫信號量(rw_semaphore)
- 自旋鎖(spinlock)
- 大內核鎖(BKL,Big Kernel Lock)
- 讀寫鎖(rwlock)
- 大讀者鎖(brlock-Big Reader Lock)
- 讀-拷貝修改(RCU,Read-Copy Update)
- 順序鎖(seqlock)
死鎖
原因
- 系統資源不足
- 資源分配不當
- 進程運行推進順序不合適
產生條件
- 互斥
- 請求和保持
- 不剝奪
- 環路
預防
- 打破互斥條件:改造獨佔性資源爲虛擬資源,大部分資源已無法改造。
- 打破不可搶佔條件:當一進程佔有一獨佔性資源後又申請一獨佔性資源而無法滿足,則退出原佔有的資源。
- 打破佔有且申請條件:採用資源預先分配策略,即進程運行前申請全部資源,滿足則運行,不然就等待,這樣就不會佔有且申請。
- 打破循環等待條件:實現資源有序分配策略,對所有設備實現分類編號,所有進程只能採用按序號遞增的形式申請資源。
- 有序資源分配法
- 銀行家算法
文件系統
- Windows:FCB 表 + FAT + 位圖
- Unix:inode + 混合索引 + 成組鏈接
主機字節序與網絡字節序
主機字節序(CPU 字節序)
概念
主機字節序又叫 CPU 字節序,其不是由操作系統決定的,而是由 CPU 指令集架構決定的。主機字節序分爲兩種:
- 大端字節序(Big Endian):高序字節存儲在低位地址,低序字節存儲在高位地址
- 小端字節序(Little Endian):高序字節存儲在高位地址,低序字節存儲在低位地址
存儲方式
32 位整數 0x12345678 是從起始位置爲 0x00 的地址開始存放,則:
內存地址 | 0x00 | 0x01 | 0x02 | 0x03 |
---|---|---|---|---|
大端 | 12 | 34 | 56 | 78 |
小端 | 78 | 56 | 34 | 12 |
大端小端圖片
判斷大端小端
判斷大端小端:可以這樣判斷自己 CPU 字節序是大端還是小端
#include <iostream>
using namespace std;
int main()
{
int i = 0x12345678;
if (*((char*)&i) == 0x12)
cout << "大端" << endl;
else
cout << "小端" << endl;
return 0;
}
各架構處理器的字節序
- x86(Intel、AMD)、MOS Technology 6502、Z80、VAX、PDP-11 等處理器爲小端序;
- Motorola 6800、Motorola 68000、PowerPC 970、System/370、SPARC(除 V9 外)等處理器爲大端序;
- ARM(默認小端序)、PowerPC(除 PowerPC 970 外)、DEC Alpha、SPARC V9、MIPS、PA-RISC 及 IA64 的字節序是可配置的。
網絡字節序
網絡字節順序是 TCP/IP 中規定好的一種數據表示格式,它與具體的 CPU 類型、操作系統等無關,從而可以保重數據在不同主機之間傳輸時能夠被正確解釋。
網絡字節順序採用:大端(Big Endian)排列方式。
頁面置換算法
在地址映射過程中,若在頁面中發現所要訪問的頁面不在內存中,則產生缺頁中斷。當發生缺頁中斷時,如果操作系統內存中沒有空閒頁面,則操作系統必須在內存選擇一個頁面將其移出內存,以便爲即將調入的頁面讓出空間。而用來選擇淘汰哪一頁的規則叫做頁面置換算法。
分類
- 全局置換:在整個內存空間置換
- 局部置換:在本進程中進行置換
算法
全局:
- 工作集算法
- 缺頁率置換算法
局部:
- 最佳置換算法(OPT)
- 先進先出置換算法(FIFO)
- 最近最久未使用(LRU)算法
- 時鐘(Clock)置換算法