面試題
1. 進程與線程的區別?(高頻面試題)
1.1 概念
進程:是併發執行的程序在執行過程當中分配和管理資源
的基本單位,是一個動態概念,競爭計算機系統資源的基本單位。
線程:是進程的一個執行單元,是進程內科調度實體。比進程更小的獨立運行的基本單位。線程也被稱爲輕量級進程。面試
一個程序至少一個進程,一個進程至少一個線程。
算法
1.2 爲何會有線程?
[!NOTE]
每一個進程都有本身的地址空間,即進程空間,在網絡或多用戶換機下,一個服務器一般須要接收大量不肯定數量用戶的併發請求,爲每個請求都建立一個進程顯然行不通(系統開銷大響應用戶請求效率低),所以操做系統中線程概念被引進。服務器
- 線程的執行過程是線性的,儘管中間會發生中斷或者暫停,可是進程所擁有的資源只爲改線狀執行過程服務,一旦發生線程切換,這些資源須要被保護起來。
- 進程分爲單線程進程和多線程進程,單線程進程宏觀來看也是線性執行過程,微觀上只有單一的執行過程。多線程進程宏觀是線性的,微觀上多個執行操做。
- 線程的改變只表明CPU的執行過程的改變,而沒有發生進程所擁有的資源的變化。
1.3 進程線程的區別?
- 地址空間:同一進程的線程共享本進程的地址空間,而進程之間則是獨立的地址空間。
- 資源擁有:同一進程內的線程共享本進程的資源如內存、I/O、cpu等,可是進程之間的資源是獨立的。
- 一個進程崩潰後,在保護模式下不會對其餘進程產生影響,可是一個線程崩潰整個進程都死掉。因此多進程要比多線程健壯。
- 進程切換時,消耗的資源大,效率高。因此涉及到頻繁的切換時,使用線程要好於進程。一樣若是要求同時進行而且又要共享某些變量的併發操做,只能用線程不能用進程
- 執行過程:每一個獨立的進程程有一個程序運行的入口、順序執行序列和程序入口。可是線程不能獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
- 線程是處理器調度的基本單位,可是進程不是。
- 二者都可併發執行。
1.4 優缺點
- 線程執行開銷小,可是不利於資源的管理和保護。線程適合在SMP機器(雙CPU系統)上運行。
- 進程執行開銷大,可是可以很好的進行資源管理和保護。進程能夠跨機器前移。
1.5 什麼時候使用多進程,什麼時候使用多線程?
- 對資源的管理和保護要求高,不限制開銷和效率時,使用多進程。
- 要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多線程。
2. 進程有哪幾種狀態?
- 就緒狀態:進程已得到除處理機之外的所需資源,等待分配處理機資源
- 運行狀態:佔用處理機資源運行,處於此狀態的進程數小於等於CPU數
- 阻塞狀態: 進程等待某種條件,在條件知足以前沒法執行
![進程與線程的區別](http://static.javashuo.com/static/loading.gif)
3. 線程同步的方式及緣由?
- 互斥量:採用互斥對象機制,只有擁有互斥對象的線程纔有訪問公共資源的權限。由於互斥對象只有一個,因此能夠保證公共資源不會被多個線程同時訪問。
- 信號量:它容許同一時刻多個線程訪問同一資源,可是須要控制同一時刻訪問此資源的最大線程數量。
- 事件(信號):經過通知操做的方式來保持多線程同步,還能夠方便的實現多線程優先級的比較操做。
4. 線程間的通訊機制?
管道(pipe)及命名管道(named pipe):管道可用於具備親緣關係的父子進程間的通訊,有名管道除了具備管道所具備的功能外,它還容許無親緣關係進程間的通訊;網絡
- 信號(signal):信號是一種比較複雜的通訊方式,用於通知接收進程某個事件已經發生;
- 消息隊列:消息隊列是消息的連接表,它克服了上兩種通訊方式中信號量有限的缺點,具備寫權限得進程能夠按照必定得規則向消息隊列中添加新信息;對消息隊列有讀權限得進程則能夠從消息隊列中讀取信息;
- 共享內存:能夠說這是最有用的進程間通訊方式。它使得多個進程能夠訪問同一塊內存空間,不一樣進程能夠及時看到對方進程中對共享內存中數據得更新。這種方式須要依靠某種同步操做,如互斥鎖和信號量等;
- 信號量:主要做爲進程之間及同一種進程的不一樣線程之間得同步和互斥手段;
套接字:這是一種更爲通常得進程間通訊機制,它可用於網絡中不一樣機器之間的進程間通訊,應用很是普遍。多線程
5. 守護、殭屍、孤兒進程的概念?
[!NOTE]
在操做系統領域中,孤兒進程指的是在其父進程執行完成或被終止 後仍繼續運行的一類進程。併發
5.1 基本概念
在類UNIX系統中,殭屍進程是指完成執行(經過 exit 系統調用,或運行時發生致命錯誤或收到終止信號所致)但在操做系統的進程表中仍然有一個表項(進程控制塊PCB),處於"終止狀態 "的進程。函數
在一個多工的電腦做業系統中,守護進程(英語:daemon,英語發音:/ˈdiːmən/或英語發音:/ˈdeɪmən/)是一種在後臺執行的電腦程序。 此類程序會被以進程的形式初始化。 守護進程程序的名稱一般以字母「d」結尾:例如,syslogd就是指管理系統日誌的守護進程。操作系統
我的理解:線程
通常狀況下,子進程是由父進程建立,而子進程和父進程的退出是無順序的,二者之間都不知道誰先退出。正常狀況下父進程先結束會調用 wait 或者 waitpid 函數等待子進程完成再退出,而一旦父進程不等待直接退出,則剩下的子進程會被init(pid=1)進程接收,成會孤兒進程。(進程樹中除了init都會有父進程)。日誌
若是子進程先退出了,父進程還未結束而且沒有調用 wait 或者 waitpid 函數獲取子進程的狀態信息,則子進程殘留的狀態信息( task_struct 結構和少許資源信息)會變成殭屍進程。
守護進程( daemon) 是指在後臺運行,沒有控制終端與之相連的進程。它獨立於控制終端,一般週期性地執行某種任務 。 守護進程脫離於終端是爲了不進程在執行過程當中的信息在任何終端上顯示而且進程也不會被任何終端所產生的終端信息所打斷 。
5.2 危害
孤兒進程結束後會被 init 進程善後,並無危害,而殭屍進程則會一直佔着進程號,操做系統的進程數量有限則會受影響。
5.3 解決
通常殭屍進程的產生都是由於父進程的緣由,則能夠經過 kill 父進程解決,這時候殭屍進程就變成了孤兒進程,被 init 進程接收
6. 什麼是死鎖?死鎖產生的條件?如何避免死鎖
[!NOTE]
多個進程在運行過程當中因爭奪資源而形成的一種僵局。當一個進程請求資源時,若是該資源不能當即得到,那麼進程就會進入等待狀態。若是一個處於等待狀態的進程 P1,因爲所等待的資源被另外一個處於等待狀態的進程 p2 所佔有,而 p2 所請求的資源又被 p1 佔有,這樣它們所請求的資源都不會得到,兩進程一直處於等待狀態,造成死鎖。
6.1 死鎖產生的緣由?
- 由於系統資源不足。
- 進程運行推動的順序不合適。
- 資源分配不當等。
6.2 死鎖產生的條件?
- (1)互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
- (2)請求與保持條件(Hold and wait):已經獲得資源的進程能夠再次申請新的資源。
- (3)非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
- (4)循環等待條件(Circular wait):系統中若干進程組成環路,該環路中每一個進程都在等待相鄰進程正佔用的資源。
6.3 如何避免死鎖?
- (1)打破互斥條件:改造獨佔性資源爲虛擬資源,大部分資源已沒法改造。
- (2)打破不可搶佔條件:當一進程佔有一獨佔性資源後又申請一獨佔性資源而沒法知足,則退出原佔有的資源。
- (3)打破佔有且申請條件:採用資源預先分配策略,即進程運行前申請所有資源,知足則運行,否則就等待,這樣就不會佔有且申請。
- (4)打破循環等待條件:實現資源有序分配策略,對全部設備實現分類編號,全部進程只能採用按序號遞增的形式申請資源
7. 操做系統的調度算法有哪些?
[!NOTE]
FCFS(先來先服務),優先級,時間片輪轉,多級反饋
- 先來先服務(FCFS):此算法的原則是按照做業到達後備做業隊列(或進程進入就緒隊列)的前後次序選擇做業(或進程)
- 短做業優先(SJF:Shortest Process First):這種算法主要用於做業調度,它從做業後備序列中挑選所需運行時間最短的做業進入主存運行。
- **時間片輪轉調度算法:當某個進程執行的時間片用完時,調度程序便終止該進程的執行,並將它送到就緒隊列的末尾,等待分配下一時間片再執行。而後把處理機分配給就緒隊列中新的隊首進程,同時也讓它執行一個時間片。這樣就能夠保證隊列中的全部進程,在已給定的時間內,均能得到一時間片處理機執行時間。
- 高響應比優先:按照高響應比(已等待時間+要求運行時間)/要求運行時間 優先的原則,在每次選擇做業投入運行時,先計算此時後備做業隊列中每一個做業的響應比RP。選擇最大的做業投入運行。
- 優先權調度算法:按照進程的優先權大小來調度。使高優先權進程獲得優先處理的調度策略稱爲優先權調度算法。注意:優先數越多,優先權越小。
- 多級隊列調度算法:多隊列調度是根據做業的性質和類型的不一樣,將就緒隊列再分爲若干個隊列,全部的做業(進程)按其性質排入相應的隊列中,而不一樣的就緒隊列採用不一樣的調度算法。
8. 系統調用與庫函數的區別?
系統調用是最底層的應用,是面向硬件的。而庫函數的調用是面向開發的,至關於應用程序的API(即預先定義好的函數)接口;
各個操做系統的系統調用是不一樣的,所以系統調用通常是沒有跨操做系統的可移植性,而庫函數的移植性良好(c庫在Windows和Linux環境下均可以操做);
庫函數屬於過程調用,調用開銷小;系統調用須要在用戶空間和內核上下文環境切換,開銷較大;
庫函數調用函數庫中的一段程序,這段程序最終仍是經過系統調用來實現的;系統調用調用的是系統內核的服務。
在全部的ANSI C編譯器版本中,C庫函數是相同的 |
各個操做系統的系統調用是不一樣的 |
它調用函數庫中的一段程序(或函數) |
它調用系統內核的服務 |
與用戶程序相聯繫 |
是操做系統的一個入口點 |
在用戶地址空間執行 |
在內核地址空間執行 |
它的運行時間屬於「用戶時間」 |
它的運行時間屬於「系統」時間 |
屬於過程調用,調用開銷較小 |
須要在用戶空間和內核上下文環境間切換,開銷較大 |
在C函數庫libc中有大約300個函數 |
在UNIX中大約有90個系統調用 |
典型的C函數庫調用:system fprintf malloc |
典型的系統調用:chdir fork write brk; |