寫一點OS的基礎知識,面試中持續更新...面試
基基礎知識算法
1.計算機硬件:輸入/輸出設備,存儲器,運算器,控制器。數據庫
2.三種基本OS類型:編程
批處理OS:單道批處理(CPU利用率低),多道批處理(缺少交互性)安全
分時OS:時間片輪轉分配;多線程
實時OS:及時響應,高可靠性併發
3.最基本特徵:併發和共享異步
4. 並行與併發:並行:真正意義上的同時執行,而併發仍是一個接一個的執行,在一段時間內獲得時間片輪轉進行執行,一段時間後執行完畢,宏觀上並行。socket
進程&線程相關函數
1. 概念:程序在一個數據集合上的一次運行過程,是OS資源分配的基本單位;
2. 動態、併發、獨立、異步,一個程序能夠包含多個進程;
3. 組成:程序、數據、PCB(標識符、狀態-阻塞、就緒、執行)、優先級、CPU現場保護區、家族聯繫(父子自之間的關係)、佔有資源的清單
4. 狀態:就緒阻塞和執行,三個隊列。當就緒狀態發生進程調度是,進入執行狀態,執行狀態請求資源(好比IO操做)沒法知足是發生阻塞,被丟入阻塞隊列,當資源被知足時完成功能後進入就緒狀態;
5. 核心態和用戶態:核心態擁有搞特權,能夠執行全部指令,訪問全部寄存器和存儲區;用戶態低特權,只能訪問部分存儲區,執行部分指令。
6.建立:通常使用fork()函數建立子進程,要注意殭屍進程的出現,如何解決?在UNP中有說明:使用信號函數signal捕獲SIGCHLD信號,使用相應函數處理(使用waitpid)。
7.線程:OS進行調度的基本單位,贊成進程內的全部縣城共享進程的內存空間(資源),他們只擁有本身的程序計數器、棧和少許寄存器。
8. 建立:pthread_create(tid, 函數,參數)
9. 回收:其餘線程使用pthread_join()來回收,或者在線程函數中設置線程脫離pthread_detach()使得執行完函數以後自行結束;
進程線程的不一樣:
9.1. 調度的基本單位和資源分配的基本單位;
9.2. 是否擁有資源:進程擁有,線程只擁有少許寄存器和程序計數器還有棧;
9.3. 開銷:建立開銷,進程要涉及分配內存空間,因此要比線程慢,撤銷也相似;特別的切換開銷,進程的現場保護要比線程複雜,進程要切換內存空間,而後切換棧和相關寄存 器,而線程只須要後面的步驟,不須要切換內存空間,因此快。(UNP說線程建立可能要比進程快10~100倍)。
9.4. 通訊:進程間因爲內存空間隔離,因此要跨內存空間來通訊(使用管道,消息隊列,共享內存,信號量,socket套接字),而線程經過全局便來個就可進進行通訊。
9.5.適用場景:多線程適用於多機,而多線程適用於多核;
10.進程間通訊(IPC)
管道:匿名管道和命名管道,匿名管道只能用於具備親緣關係的進程之間,而命名管道能夠用於通常的進程之間;Linux頭文件<pipe.h>
消息隊列:建立消息隊列,一個進程去讀,另外一個去寫;頭文件:<mqueue.h>,mq_open()和mq_clos();
共享內存:最快的一種IPC方式,爲何快?由於他直接將進程的進程空間映射到要使用的內存空間中,這樣就避免了其餘方式中的與內核緩衝區交互的時間開銷。(其餘的方式通常都是將設局寫入進程緩衝區,然後進入內核緩衝區,而後另外一個進程再從內核緩衝區中將數據讀到本身的進程緩衝區中)<sys/mman.h>
socket:一種能夠實現遠端進程通訊的一種方式。Linux頭文件<sys/socket.h>
(TCP/UDP各有編程範式)
11.進程同步:
互斥鎖:pthread_mutex_t,pthread_mutex_lock/trylock/unlock
讀寫鎖:讀鎖和寫鎖,讀鎖共享,寫鎖互斥。和數據庫的讀寫鎖相似。
信號量:<semaphore.h>sem_open()/wait/trywait(),實例就是操做系統都作過的生產者消費者這問題
條件變量:pthread_cond_t signal()和wait()函數,一般和互斥量一塊兒使用。
記錄鎖:對記錄上鎖,典型例子時文件鎖。
12. 做業調度算法
12.1 先來先服務FCFS:就是先來的(在就緒隊列頭部的)先調度執行,後面的通通等着。(這讓我想起了今早上宿舍中一舍友上廁所上了半個小時...我也很急,但又不能搶佔資源...無奈的我只得尋找另外一臺主機,成爲他的一個臨時進程)
12.2 短做業優先SJF:就是短的先執行。對長做業很是不友好,致使長做業「飢餓」。
12.3 優先級調度PSA:爲做業肯定優先級,從後備隊列中選取優先級高的裝入內存。
12.4 高響應比優先:每次選取響應比較高的做業裝入內存(響應比:(等待時間+運行時間)/等待時間),這種算法考慮了等待時間的因素。
13. 死鎖
一組進程隊列中,每一個進程都等待其餘進程所持有的資源,形成循環等待的局面。
4個條件:互斥條件、請求與保持、不可剝奪、環路條件
如何預防:從234條件下手,請求須要先釋放、能夠高優先級剝奪、爲每一類資源進行編號,請求高的須要先釋放低的。
如何避免:銀行家算法,搞清需求,進行預分配,判斷是否能找到一個安全狀態。
如何檢測:資源分配圖可否徹底化簡;
如何解決:1.終止進程(所有終止;按照次序終止,直到死鎖狀態解除);2. 付出代價最小的解除算法
(這裏我又想起了,InnoDB存儲引擎處理死鎖的方法:rollback持有最多互斥鎖的事務)
14. 虛擬存儲器
在我看來,虛擬存儲器並未從實際上擴充物理內存。而是經過換頁技術「看起來像是」擴充了物理內存。用到的原理涉及時間局部性和空間局部性。
在運行初始,只把必要的程序裝入內存頁,運行時若是發生缺頁再進行缺頁置換,置換的算法著名的有LRU(最近最少使用算法),原理是使用過的程序和數據,頗有可能會在一段時間後繼續訪問。
這樣就能夠將一個很是大的軟件或程序運行起來,只不過是換頁技術在其做用而已。
15. 物理內存與虛擬內存
物理內存對應於物理地址,虛擬內存對應於邏輯地址,它們之間存在一個映射關係。
1. CPU訪問一個邏輯地址時,須要將邏輯地址分解成爲一個組號和組內地址;根據組號去查地址轉換表,肯定該組信息是否在內存中;
2. 若是該組號已經在內存(主存)中,那麼從地址轉換表中讀出對應的物理組號;並根據物理組號和組內邏輯地址,存取必要的信息;
3. 若是該組號不在內存中,那麼發生缺頁中斷,須要將存儲在磁盤(輔存)上的信息讀入內存中,若是有空閒頁,直接讀入,不然須要選定頁置換出內存,再把須要的信息換入內存中,並更新地址轉換表。
缺頁置換的算法
1.隨機算法:生成一個隨機數,來肯定將那一頁換出內存;
2.先進先出算法:將最早進入的頁換出;
3.最近最少使用算法:替換最近最不常使用的頁;LRU
4.最優算法:替換最長時間之後才使用的頁面(一個理想算法)。
16。程序編譯的過程
17.靜態連接和動態連接的比較
1. 靜態連接庫須要裝配入可執行文件中,而動態連接庫不須要;
2. 靜態連接庫函數直接在可執行文件中你,因此執行速度快;而動態連接庫,則是須要臨時去庫中尋找,因此執行速度稍慢;
3. 靜態連接致使可執行文件臃腫,而使用動態連接庫的可執行文件清爽,節約存儲空間;
4. 此外靜態連接庫還存在重複裝配的問題(#ifndef之流就是來解決他這類問題的),動態連接庫不存在此問題;
5. 靜態連接庫更新和擴展麻煩(已經連接入可執行文件了),須要從新編譯軟件,而使用動態連接庫,只須要替換動態連接庫文件便可。
18.虛擬內存
操做系統對於內存(主存)的一種管理方式。操做系統給每個進程都分配地址空間,但此地址空間是虛擬內存空間,一般比其所對應的物理空間要大許多。
當CPU要訪問某數據時,生成一個邏輯地址,而後用邏輯地址去查「頁表」,頁表上存儲着全部存儲在內存和磁盤上的數據的地址,頁表每一條記錄都至少有兩個表項,一個是有效位,另外一個是物理地址或者是磁盤地址。若是發現有效位置1,那麼證實數據在物理內存中(DRAM命中),根據另外一個表項上的物理地址去物理內存中查找讀取便可。若是,有效位置0,那麼數據不在物理內存上(未命中,發生缺頁異常)。這時,須要將磁盤上的數據加載到物理內存中來。若是物理內存有空閒頁,那麼直接讀進來便可,而後更新頁表便可,而後從新查找頁表,去讀取須要的數據。若是,物理內存頁都被佔用,那麼須要「頁面置換」,採用「先進先出,LRU,理想方法」等方法能夠將合適的頁面調換出物理內存,而將磁盤上的數據頁換到內存中來,一樣更新頁表,從新查找讀取數據。
做用:內存管理和保護的工具 (PS CS:APP 《深刻理解計算機系統》 真的是一本奇書,NB!!!)
(圖源Baidu)