# 作業系統筆記
## chapter 1
電腦的基本架構:

作業系統核心概念:
* 資源分配器
* Manages all resources
* Decides between conflicting requests for efficient and fair resource use
* 控制程式
* Controls execution of programs to prevent errors and improper use of the computer
* interupt base : 呼叫才會做處理
* 作業系統中永遠運行的程式就是kernel,除了kernel以外的,都叫system program或application program
* CPU會把資料從memory裡丟到local buffer,然後memory會直接跟buffer做溝通

* interrupt比喻:櫃台叫你去填表單,填完後再告訴他,你填東西的這段時間,櫃台還可以服務其他人
* device drive(hardware)或application(software)做完後,會發出interrupt告訴CPU任務做完了
* interrupt handling
* polling:一個一個檢查誰需要interrupt
* vector:回傳一個值告訴作業系統誰需要interrupt,較有效率,OS大多採用這個
* Storage-Device Hierarchy 越往下越慢,容量越大

* bootstrap program:把kernel load進去
* timesharing:透過很短暫的時間快速切換工作,讓user有種OS只服務他一人的感覺(時間管理大師)
* Memory Layout for Multiprogrammed System

* dual mode : 有些東西不能讓使用者直接碰觸到,所以要有區分
* user mode : user可以直接存取呼叫
* kernel mode : user要透過system call來存取呼叫
* system call : 讓user存取system program的介面,user呼叫interrup,讓kernel去存取受到限制的資源(kernel mode)

## chapter 2
* Operating System Services
* User interface
* Program execution
* I/O operations
* File-system manipulation
* Communications
* Error detection
* Resource allocation
* Accounting
* Protection and security
* 作業系統為甚麼不採取完全沒有錯誤的方法:會運行的很慢,找出問題並解決,才是重點
* 作業系統架構:

* API:再對system call做一層包裝,因為sys call會隨版本更新變動,透過一個共用介面來簡化程式
* 一個sys call後會做非常多事

* 只服務一個user single tasking,memory只有一個process:

* 單晶片,沒有作業系統,用bootloader載入程式,更簡單基本

* 多人多工OS,memory有多個process

* link and load
* link:把函式庫link進二進位檔
* load:把執行檔從disk載入到memory

* monolithic structure:UNIX使用,不把系統分太細,主要分為兩大塊:
* system programs
* the kernel
* system call interface
* file sys、CPU scheduling、memory management...
* UNIX的架構,沒有layer的概念:

* linux structure:在unix加入modular design
* 原先的設計是有新的裝置controller要加入,整個系統就要重新compile
* modular:可以把一些功能load到kernel裡,不用重新compile
* layer approach:
* 每一層depend on上一層
* 沒效率,因為底下operation都會做到
* 中間的層難以排序,沒有一定的相依性

* micro kernel:減少kernel大小,需要用到時再從user space載入到kernel

## chapter 3
* process:執行檔load到memory後就稱為process

* memory layout

* 程式 to 程序
* 程式檔案的頭部會存放資訊告訴OS怎麼把它放到記憶體裡,程式進入點在哪
* windows: PE(Portable Executable) Header
* Linux:ELF(Executable and Linkable Format)
* process state

* 前面的layout沒有儲存process state的資訊,所以要有PCB(process control block)

* 一個process對應一個PCB
* PCB內會有pointer指向真實在memory的位址
* CPU Switch From Process to Process

* context snapshot:將被switch out的process的資訊(register、IO、進度)存回PCB,讓下一次再選到這支process執行時,可以重新載入
* process內可能會有很多thread,可以假想成有很多program counter在跑
* process含有兩大部分,PCB與process真實存放的記憶體位址

* PCB與PCB之間會用雙向linked list連接
* process scheduling
* 為了避免去檢查整個list,所以用queue存放,增加效率
* ready queue : 存已經可以執行的process的PCB
* wait queues : 存還不能馬上執行(等待IO、...)的process的PCB
* 
* schedulers
* long term/job scheduler : 每幾秒甚至每幾分鐘才執行一次,挑一批process進入ready queue,限制多少process可以進入ready queue
* 會盡量讓I/O 與 CPU bound process各佔一半比例,避免太多人排隊給CPU執行
* 隨著電腦越來越強,這種機制已漸漸被淘汰
* short term/CPU scheduler : 幾ms執行一次,挑一個process執行,限制每個process可以執行的時間
* medium term scheduler : 因為某些原因導致ready queue內放的不是想要的,這時候就用swapping
* swapping : 把process直接從memory丟到disk去(並非丟執行檔,而是記憶體原封不動的丟)
* 比喻:long term->會議室外的等待空間,short term->每個人可以報告的時間
* context switch
* context就是PCB
* context switch的時間,CPU無法做任何事
* context switch時間減少,CPU效率提升
* process creation
* 用parent產生children的概念
* 會用parent process來產生新process是因為這樣會更方便複製process的資料結構也就是直接把parent複製一份fork,然後改pid即可
* 父子process可以share記憶體,所以設計可以非常靈活
* 
* process在fork完後才會將執行檔load進memory,然後存指標到PCB
* 父process會等待子process結束後才能結束
* 執行一個程式 : 父process執行fork -> 子process執行exec
* fork,假設child的pid都為0
* fork回傳的是自己的pid,並非child process的pid
* fork完後產生child,parent與child除了pid之外都一模一樣
* 當CPU選中child去執行時,就會跑到case pid==0裡,然後執行exec把這段程式碼蓋掉成想要的

* process termination : process結束後釋放記憶體
* parent process有權限把child process終止,以避免沒有把記憶體釋放乾淨
* thread概念:一個process裡有不同的program counter,所以一個process裡可能有多個TCB(thread control block)
* chrome記憶體用量大原因:每開一個分頁就是一個process,會這樣做是為了避免某個分頁掛掉,其他分頁也跟著掛掉
* interprocess communication(IPC)
* shared memory : 兩個process共用一塊記憶體,存取快速便利,但不安全
* 問題:要如何解決寫入到一半時被interrupt後,造成其他人讀取到不正確的值?(同步問題)
* message passing : process之間透過類似system call的方式從kernel讀取共用的記憶體,較安全
* 
* communication
* direct : 直接發送接收資訊,1對1
* indirect : 放到mailbox,別人再從mailbox拿出來
* synchronization
* blocking : 等到receive完後才能結束send,等到send完所有message後才能receive
* non-blocking : 丟完後就可以結束send,接受訊息也不管有沒有正確
* pipe : 用父子process的關係讓溝通變簡單(約定某塊記憶體收發訊息)
* remote procedure call(RPC):執行遠端電腦的system call或程式
## chapter 4
* Single and Multithreaded Processes
* 一個PCB可能指向多個TCB(依實作而定)

* 為何要用thread : 不用每次都複製一大堆相同程式碼,節省記憶體
* Responsiveness
* Resource Sharing
* Economy
* Scalability
* concurrency : 快速切換來同時運行多個task,但實際上同時只執行一個
* parallelism : 用multicore來同時執行多個task,真正意義上的同時執行多個
* data parallelism : 資料分成不同core來執行,某段只由一個core執行
* task parallelism : 同一段資料可能有多個core來執行

* user and kernel threads
* 
* many to one : 有一個thread call system call後就interrupt process,造成其他thread也跟著被暫停
* one to one : user thread自動產生或對應到一個kernel thread,library與kernel息息相關
* many to many : 可以提供1對1,也可以提供多對多,自動判斷如何對應(檢查thread pool)
* two level : kernel thread被綁定在user thread
* implicit threading : compiler自動幫你multithread,但並沒有在程式碼裡實作multithread,顯性則反之
* fork-join parallelism : compiler自動把task切割fork出去執行,然後把結果join起來
* grand central dispatch : runtime時才變成multithread
* serial queue: 序列化執行,無法平行化的程式會丟到這個queue
* concurrent queue: 平行化執行
* multithread process執行exec後會將所有thread覆蓋掉
* multithread下的fork有兩種
* 複製所有thread
* 只複製執行到fork的thread : 通常會用後fork後馬上exec
* signal handling : 其他process對發生例外狀況的process發出通知,做後續處理(關閉某個或某些thread)
* thread cancellation
* asynchronous : 立即cancel thread
* deferred : 檢查現在是否可以被cancel,不行的話就等待thread做完後才cancel
* off : 無法被cancel
* thread-local storage(TLS) : 存一些function與function之間的information,thread特有的資訊
* scheduler activations : user thread與kernel thread之間溝通的流程
* light weight process(LWP) : 存user thread與kernel thread之間的關聯對應資訊的資料結構,位於kernel space
* 讓user thread以為LWP是一個virtual process
* 
* 每個user thread都會對應到一個LWP,LWP也只會對應到一個user thread,但可能對應到多個kernel thread
* upcall : kernel thread通知user thread訊息
* 可以是kernel thread產生多個LWP,也可以是多個LWP assign到不同的kernel thread,有很多種做法
* LWP就是user thread在kernel的代理人
## chapter 5
* CPU scheduler : 在ready queue中尋找下一個適合的process執行,雖然真正的最小執行單位是thread,但是存放的資訊還是在process裡,所以scheluder是選擇process而不是thread,process選完後才近一步選thread,thread再去選用哪個CPU來執行。
* preemptive vs non-preemptive
* preemptive : 執行到一半時可能因scheduler而被強制交出CPU使用權,有效率
* non-preemptive : 會等到該process離開running state後才執行scheduler,running自己主動呼叫scheduler的情形就屬於non-preemptive,沒效率
* 呼叫scheduler時機 #必考
* running state to waiting state (做IO) => non-preemptive
* running to ready state (interrupt occurs、時間用光了) => preemptive
* waiting to ready (IO完成),比喻:填完表單的人可以讓櫃台決定要不要先服務你,而不用從頭開始排隊 => preemptive
* running terminate (執行結束) => non-preemptive

* dispatcher : scheduler選好下個process後,就交給dispatcher,做以下處理:
* context switch
* 把現在的process存回PCB
* 把選定的下個process的PCB資訊載入到CPU register
* switching to user mode
* user mode之間的轉換
* jumping to the proper location in the user program to restart that programjum
* program counter指到接下來要執行的process的程式碼
* dispatch latency : 執行dispatch的時間

* 沒有人可以打斷dispatch,比喻:皇帝旁的太監
* scheduling criteria
* CPU utilization : CPU越忙越好,榨乾時間
* throughput : 單位時間處理越多process越好
* turnaround time : 每個process從開始處理到結束的時間越短越好
* waiting time : process在ready queue裡等待時間越短越好
* response time : 從request到response的時間越短越好
* 不可能全部都同時優化
* First Come First Served(FCFS) : 依據進來的順序去執行,也就是直接拿ready queue的第一個element
* 
* 但average waiting time是17,如果先做P2、P3,可以讓average waiting time減少
* 
* convoy effect : 讓short process先做,就可以降低waiting time
* 為了降低waiting time,所以有了SJF
* Shortest Job First (SJF)
* 但問題是還沒執行前都不知道burst time是多少,所以通常用預估的方式來決定burst time

* 預估方法:

* EX: 下一次預估 = 本次預估\*0.5 + 實際時間\*0.5

* shortest remaining time first : FCFS與SJF結合
* 看剩多少時間要執行,先選最少的,此方法為preemtive,如果出現一個更少剩餘時間的process,就會強制切換
* 
* priority scheduling
* 選低priority值的process執行
* Round Robin
* 每個process執行一段時間(time quantum q)就換人,一直輪流下去
* time quantum q usually 10-100 ms,context switch < 10us
* quantum 通常設計為 80% of CPU bursts should be shorter than q

* 在現實中很少見,因為人腦無法快速切換工作
* Multilevel queue : 把不同種類的process丟到不同的queue,現在OS大多用這種方法
* 用不同排程演算法處理不同queue

* queue之間也有priority

* Multilevel Feedback queue : process可以在不同queue之間移動,會有一些機制來把process丟到其他queue,避免等太久
* 各種排程的比較

* 期中必考1

* 期中必考2



* Multiple Processor scheduling
* Homogeneous processors : processor之間的運算能力是一樣的
* Asymmetric multiprocessing : 有一個專門負責scheduling的processor
* Symmetric multiprocessing(SMP) : 現代OS常用,每個processor自己決定CPU scheduling
* 所有thread存在common ready queue
* 所以多個processor有可能選到同一個thread,產生大問題
* 因此現在改變為每個processor都有一個ready queue
* 每個thread會被分配到不同的ready queue裡
* 把所有multiple processor放到同一個chip就叫multicore processor
* Multithreaded Multicore System
* 趁其他thread在存取記憶體時切換到另一個thread執行

* Chip-multithreading : 每個core裡都有2條hardware thread,完全由硬體實現,會多一套register來存另一個thread的register值
* hyperthreading in Intel

* two level of schduling
* kernel thread對應到hardware thread就會用前面提到的排程演算法

* load balancing : 不讓每個CPU上面放的task太多
* push migration : 把overloaded CPU的task push到其他CPU
* pull migration : 閒置的CPU把task從overloaded CPU拉過來
* Processor Affinity : 盡量讓task留在同一個CPU,讓快取起到作用
* soft affinity : OS想辦法讓task只在一個CPU上執行,但不保證
* hard affinity : 保證task只在某幾個CPU上執行
* Non-uniform memory access (NUMA) :
* 移動task後,CPU就要存取到其他CPU的memory,這樣的速度很慢
* 因此盡量避免移動task到其他CPU
* 
* 一個core同時只能處理一個hardware thread,這是concurrency而非parallelism
* Real time CPU scheduling : 要求在很準確時間執行的task(EX火箭),不能被其他process影響
* soft real-time : priority高的先處理,但無法保證高priority一定可以被schedule
* hard real-time : 一定滿足條件,重點放在執行的時間
* event latency : event發生到被serve的這段時間
* interrupt latency : interrupt進來後直到執行完interrupt的時間
* dispatch latency : 選好下個process到執行完dispatch的時間
* 
* dispatch有可能conflict,也就是要等別人處理完資料,花額外時間去處理conflict
* preemptive,priority based scheduling : 一個更緊急的事件出現後,要把現在的process換掉
* 每個thread會periodic的出現,每p秒出現一次,執行t秒(event latency),deadline是d
* 需求 : 0 ≤ t ≤ d ≤ p
* 
* Rate Montonic Scheduling
* 給每個thread或process一個period或priority,週期越長,priority越低,週期越短,表示常常執行,priority越高

* missed deadline

* 公式算出來是83%小於2個utilization相加的0.94,因此會miss
* Earliest Deadline First Scheduling(EDF) : 依據離deadline的時間來排程

* 最佳theoretically optimal solution 比rate montonic好
* 但經常切換,所以要考慮到context switch的時間,所以不一定適用所有狀況
* Proportional Share Scheduling
* 所有process有T個share
* 現在已經有N個share
* 
* 判斷D進來後是否有辦法分配下去,無法的話就拒絕
* linux scheduling
* version 2.4
* global runqueue/expired queue
* 把所有thread丟到runqueue
* runqueue的process執行完後丟到expired,直到runqueue都被執行完後,就開始執行expired queue
* 高priority得到更大的quantum
* version 2.5
* priority從0~140,用140個queue的array存放所有thread
* CPU可以直接從priority最高的queue內拿出thread
* 有thread存於queue的priority就會把該priority的bit變為1,使搜尋時間達到O(1)
* 高priority得到更大的quantum
* version 2.6.23
* completely fair scheduler(CFS) : 值的部分重新設計
* 
* virual run time : 記錄每個thread用了多少時間
* 根據virual run time來決定下個選誰,不只考慮priority
## chapter 6 & 7
* race condition : 多個process在同時競爭(使用)相同的資源,結果與存取資源的順序性有關連時,race condition就會發生
* Synchronization : 避免race condition的發生
* critical section problem
* critical section : 會動到與其他人share data的程式碼段落,簡稱CS
* critical section protocol : 在執行到critical section之前與之後去做一些措施保證critical section執行期間不會被schedule out
* entry section
* exit section

* solution
* mutual exclusion : 在執行critical section期間,只有該process可以做,沒有其他process可以中途插入,一定會等critical section做完
* 晚到的entry會被block起來
* 執行結束後知會其他process可以進入critical section了
* progress : 要持續進展,否則其他人會被卡死,無法執行下去
* 在多個entry中決定下個進入的entry
* bounded waiting : 要保證不會無限地等下去,遲早有天會輪到你去存取
* 不能根據速度去決定下個entry否則會不符合bounded waiting,可能有人無限等下去,永遠選不到他
* EX 
* 只判斷是不是輪到自己
* 無法滿足progress與bounded waiting條件,因為如果只有一個process,而且turn又不符合條件,就會無限等下去
* EX 
* 只判斷對方要不要做,對方要做,就等對方
* 也無法滿足progress與bounded waiting條件,如果同時執行到while,則兩邊會互相等待,無限等下去
* peterson's combined solution
* LOAD與STORE都不可被中斷
* 同時判斷 是不是輪到自己 與 對方要不要做
* 
* 滿足所有條件
* Prove the validity of a critical section?
* Mutual exclusion
– 假設兩個(以上) 的processes可以同時進出CS,找出其矛盾
* Progress
– 沒有process在CS中,一個process要進去CS,一定可以進去
– 多個process要進CS,在有限的時間內做出決定
* Bounded waiting
– 找出次數的上限
* peterson's solution

* comiler或硬體可能把`x = 100;`與`flag = true`調換順序,使Mutual exclusion條件無法符合

* 所以需要有hardware支援才能真正解決Synchronization問題
* Synchronization Hardware
* Memory barriers : 實現某些單位的memory之更改可以馬上被別人知道
* memory model
* strongly ordered : 一個processor對memory做任何動作會馬上讓其他processor知道
* weakly ordered : 以上反之
* 
* Hardware instructions : 透過硬體確保不會在執行過程中被interrupt,不滿足bounded waiting,有機會永遠等不到
* Test and Set Instruction
* 
* Compare and Swap Instruction
* 至少確保不會有多個人去使用
* 實作出lock的概念


* 在entry與exit section內都有可能發生race condition,所以其實這些解法都只是將複雜的大問題(critical section)轉化成小問題(entry與exit section),但問題本身還是存在,在讀寫lock變數時還是有機會被interrupt。
* Bounded-waiting Mutual Exclusion with compare-and-swap

* Atomic variables : 確保寫入變數時不會被interrupt
* Bakery Algorithm
* [麵包店算法](https://zh.wikipedia.org/wiki/Lamport%E9%9D%A2%E5%8C%85%E5%BA%97%E7%AE%97%E6%B3%95)

* 為何不使用hardware解決Synchronization就好?
* 因為hardware較適用於實作entry section的single且簡單的資料結構(int、bool...),而無法處理CS內複雜的資料結構(buffer、array...)
* 無法達成Bounded waiting條件,無法確保所有人都會被選中,可能一直等下去
* 解法 : 軟硬兼施,改用mutex lock或semaphore
* busy waiting : 不context switch,而是一直不斷檢查,用於context switch cost 很高的情形
* mutex lock : 在OS層面實作lock的library
* (mutual exclusion) lock
* lock變數都是使用Atomic variables
* 可以滿足三大條件
* busy waiting
* 
* Semaphore
* busy waiting
* user可以確保哪個process先執行
* 
* 
* 
* 等到P1跑完`signal(synch);`後,P2才可以進入`S2;`
* 不用busy waiting的方法?
* 改用waiting queue(list指標)


* Four Typical Uses of Semaphores
* Mutual exclusion
* Force suspend : 強制某個process先執行, Keep the execution in a particular order
* Count-down lock : 限制可以進入的process數量

* Notification : Indicate that an event has occurred

* deadlock and starvation
* starvation
* indefinite blocking
* A process may never be removed from the semaphore queue in which it is suspended.
* 
* priority inversion
* 高priority因為lock的關係導致必須等待低priority的人

* Priority Inheritance : 低priority的task卡住要高priority的task,就要把priority繼承過去,避免之後被其他較低priority的task(Task2(M)) preempt

* Monitor : 自己定義資料結構(ADT),OS會自動保證Mutual exclusion,不會有deadlock的狀況

* signal and wait : 離開去等待,通知下一個人
* signal and continue : 繼續做完剩下的事才離開

* 針對每筆資料都可以有一個condition
* 用Semaphore實作出Monitor

* What’s the different between semaphore and monitor?
* 比喻 : monitor像公廁,一個人進去其他人就不行進去
* 比喻 : semaphore像bicycle hire,大家共用某幾台bicycle
* Classical Problems of Synchronization
* Bounded-Buffer Problem
* 
* 
* 如果`wait (mutex);`與`wait (empty);`寫反,則可能造成deadlock的狀況
* Readers and Writers Problem
* 有一shared data set
* reader : 只會讀取,不會寫入data set
* writer : 可讀可寫
* problem
* 多個reader同時讀取
* 同時只能有一個writer存取
* writer寫入時,reader不能讀取
* 如果有reader在讀,writer必須等待
* Dining-Philosophers Problem

## 期中考古題

