寫在前面:此文章持續更新,對作業系統原理的學習進行復習總結。相關學習參考內容已列下方,目前水平有限,如有建議,歡迎指正!
References
- 作業系統原理[天津大學,李罡,2013](B站、優酷)
- https://github.com/CyC2018/CS-Notes
- 公眾號:Java建設者----文章:寫給大忙人看的程序和執行緒
CPU是多道系統,偽並行(單核單CPU)
程序:一段程式的正在被執行的一個範例(有「生命」的)
What is the difference between program and process ?
A process consists of three parts:
Unix中除了祖先程序,其他都是fork(「克隆」)自身出來的。共用身子(程式碼、資料),頭不一樣(Block)
The fork() system call creates a child process. The exec() system call overlays the existing process with another program. The wait() system call allows the parent process to wait for a child process to terminate. The exit() system call terminates the process.
Process States:
process termination:
Normal exit (自殺)
Error exit
Fatal error
Killed by another process (他殺)
程序是資源分配得最小單位,而程序中的執行緒共用擁有的資源。
執行緒是排程得最小單位。
程序的執行時排程內部的執行緒
Implementing Threads in User Space(使用者態、核心態)
執行緒池(待更新)
批次處理系統:CPU利用率高好
互動式系統:CPU利用率較低好,在意response time
實時系統:達到條件時,立即響應(工業鍋爐)
批次處理系統的排程:
互動式系統的排程:
臨界資源:可以共用使用,但不可以同時使用(eg. 印表機)。
臨界區(critical regions):使用臨界資源的程式碼
大於2個程序的競爭條件:
Conditions required to avoid race condition:
- No two processes nay be simultaneously insider their critical regions.
- No assumptions may be made about speeds or the number of CPUs.
- No process running outside its critical region may block other processes.
- No process should have to wait forever to enter its critical region.
解決競爭條件也分為兩大類:
忙等待方案:TSL(Test and Set Lock)。該法關鍵字:「自旋鎖」 「忙等待」 「原子性,即不可打斷」
// TSL程式碼
enter_region
// MOVE REGISTER, #1
// XCHG REGISTER, LOCK |原子性操作
TSL REGISTER, LOCK |複製lock到暫存器,並將lock置為1 (這句話實現上面兩句話) 原子性操作
CMP REGISTER, #0 | lock等於0嗎?
JNE enter_region |如果不等於0,已上鎖,再次迴圈
RET |返回撥用程式,進入臨界區
leave_region
MOVE LOCK, #0 |置lock為0
RET |返回撥用程式
Semaphore can be operated by PV operation only.
號誌只有賦初值時可以直接賦,其他只能用P和V來操作它
(注意,號誌還有等待佇列部分,不止整數部分)
Semaphore中整數部分物理含義:
P與V源語不可打斷(P下降,V上升)。源語:非常迅速,非常快,不可打斷,少量。
// 方案1:PV in Sleep abd Wakeup
P(Semaphore s)
{
s = s - 1;
if (s < 0)
{
add to the semaphore's queue and sleep;
}
}
V(Semaphore s)
{
s = s + 1;
if (s <= 0)
{
wake up the waiting process in the semaphore's queue;
}
}
// 方案2:PV in Busy Waiting
P(Semaphore s)
{
while (!s>0)
{
yield the CPU;
}
s--;
}
V(Semaphore s)
{
s++;
}
以上兩個PV均可用印表機例子來思考
方案1,佔了,就去睡覺,然後有人叫醒
方案2,忙等待,一直測一直測有沒有資源
管程 Monitors
管程可以保證不同時執行。用編譯器去編出管程,如Java中給一段程式碼加synchronized,給另一段程式碼也加synchronized,這兩段程式碼就不會同時執行。
同步問題:先檢查,後修改,中間有可能被打斷,前面檢查無效,會出錯(TSL,PV都是避免了這樣的問題)
#define N 100
typedef int semaphore;
semaphore mutex = 1; // 生產者消費者互斥存取臨界區
semaphore empty = N; // 當前空格子的個數(生產者的)
semaphore full = 0; // 滿格子的個數(消費者的)
// empty、full可以叫做通行證
void producer(void)
{
int item;
while(TRUE)
{
item = produce_item();
p(&empty);
p(&mutex);
insert_item(item);
v(&mutex);
v(&full);
}
}
void consumer(void)
{
int item;
while(TRUE)
{
p(&full); //這兩個p顛倒 + 生產者兩個p也顛倒,會發生死鎖
p(&mutex);
item = remove_item();
v(&mutex);
v(&empty);
consume_item(item);
}
}
// Mutex保護操作
int state[N]
semaphore mutex=1; // 在這種用PV的解決問題的型別中,int這種全域性變數,需加Mutex一下
讀者優先的讀寫者問題:
1.寫者、讀者互斥存取檔案資源。
2.多個讀者可以同時存取檔案資源。
3.只允許一個寫者存取檔案資源。
typedef int semaphore;
void reader(void)
{
while(TRUE)
{
down(&mutex);
rc = rc + 1;
if (rc == 1) { down(&db); }
up(&mutex);
read_data_base();
down(&mutex);
rc = rc - 1;
if (rc == 0) { up(&db); }
up(&mutex);
}
void writer(void)
{
while(TRUE)
{
down(&db);
write_data_base();
up(&db);
}
}
}
程序同步:控制多個程序按一定順序執行;
程序通訊:程序間傳輸資訊。
程序通訊是一種手段,而程序同步是一種目的。也可以說,為了能夠達到程序同步的目的,需要讓程序進行通訊,傳輸一些程序同步所需要的資訊。
可搶佔資源、不可搶佔資源(eg. 印表機)
死鎖的四個條件:
解決死鎖(忽略、檢測、避免、預防)
makefile
system call: fork()…and others
多執行緒
Primary Memory(aka RAM)
Secondary Memory(ie. hard disk)
CPU只和記憶體打交道,不和硬碟打交道
程式碼段(Text Segment):一般唯讀不可變的。
資料段(Data Segment):(靜態)大小固定。
堆區(Heap Storage):大小可變。特點是隨機存取。
棧段(Stack Segment):大小可變。特點是先進後出。高地址固定,向低地址方向擴大或縮小。
環境變數區(Environment Variables):由外部,一般為作業系統,設定的變數。
分割區管理是把整體的、連續的放進記憶體空間,帶來無法使用不連續的小空間問題(碎片)。
分割區管理定位需要基址暫存器 Base register
Memory Manager Strategies MM策略
分頁管理可以分散的放。
虛擬記憶體 Virtual Memory
虛擬記憶體的目的是為了讓實體記憶體擴充成更大的邏輯記憶體,從而讓程式獲得更多的可用記憶體。
為了更好的管理記憶體,作業系統將記憶體抽象成地址空間。每個程式擁有自己的地址空間,這個地址空間被分割成多個塊,每一塊稱為一頁。這些頁被對映到實體記憶體,但不需要對映到連續的實體記憶體,也不需要所有頁都必須在實體記憶體中。當程式參照到不在實體記憶體中的頁時,由硬體執行必要的對映,將缺失的部分裝入實體記憶體並重新執行失敗的指令。
頁表
管理頁表:
兩點注意:
中斷:恢復現場後執行被中斷點的下一條語句。
缺頁中斷:恢復現場後回來執行被中斷的這條語句。
分頁存在的問題:
分段式管理解決了分頁管理沒有邏輯內在,但又引入了分割區管理的問題(碎片)
分段,段內再分頁,即段頁式管理 Segmentation with Paging
真實實體記憶體耗盡,需要把一部分東西換出去,產生了問題,換誰?
在程式執行過程中,如果要存取的頁面不在記憶體中,就發生缺頁中斷從而將該頁調入記憶體中。此時如果記憶體已無空閒空間,系統必須從記憶體中調出一個頁面到磁碟對換區中來騰出空間。頁面置換演演算法和快取淘汰策略類似,可以將記憶體看成磁碟的快取。在快取系統中,快取的大小有限,當有新的快取到達時,需要淘汰一部分已經存在的快取,這樣才有空間存放新的快取資料。頁面置換演演算法的主要目標是使頁面置換頻率最低(也可以說缺頁率最低)。
頁表中的標誌位:
頁面置換演演算法:
頁面置換演演算法內容最好多看線上課程來理解,容易忘
Not Frequency Used
page stealer, 若頁面空間小於Min,開始偷(換),到達到Max為止。不能讓其太滿,保證記憶體空閒量處在min和max之間。
分頁與分段的比較:
記憶體 — memory
外存 — storage
記憶體資料掉電即丟,需要有些放在外存裡。
檔案包括:
檔案結構包括(unix裡檔名和屬性分開存放):
file permission 檔案許可權(之後Linux總結複習文章會總結這裡的相關內容)
目錄記錄的是檔案名字和inode對應關係
檔案系統 The Unix File System:多級索引
檔案系統:
Components of storage(由小到大):
面、柱(track,也稱磁軌)、磁區 -------->定位到data
磁碟排程演演算法:
讀寫一個磁碟塊的時間的影響因素有:
其中,尋道時間最長,因此磁碟排程的主要目標是使磁碟的平均尋道時間最短。
演演算法包括:
電梯演演算法
…
…
…
LVM
Redundant Array of Independent Disk.
RAID:更快、更可靠、映象化
RAID0、RAID1、RAID5…
RAM disks 記憶體中磁碟(為了快,如Cache)
Interrupts 中斷 ------->現代計算機必備
DMA, Direct Memory Access,用於控制一些高速的傳輸
Buffering 快取
ASCII(American Standard Code for Information Interchange),7位,7個bit(一個位元組8個bit)
GBK:國標碼
UTF8:保證了ASCII大小不變,還避免瞭如截斷某半個字問題,擴充套件了其他語言編碼。範圍最廣。
寫在結尾:
之後還會陸續更新作業系統相關知識的學習和總結
Linux相關會另外總結一篇文章
目前水平有限,如有建議,歡迎指正!