1.進程和線程以及他們的區別與聯系?
進程是程序在某個數據集合上的一次執行過程,是系統資源調度和分配的最小單位。
線程是進程的實體,是cpu調度和分派的最小單位,線程自己基本上不擁有系統資源,只擁有一些必要資源,但是他可以與同屬於一個進程的線程共享所有的資源。
一個進程可以擁有很多個線程,但是一個線程只能屬於一個進程,一個線程還可以創建多個子進程,同時多個線程可以並發執行。線程執行開銷小,但是不利於資源的管理和保護,而進程則正好相反。
2.分段和分頁以及他們的區別是什么?
頁是信息的物理單位,是為了實現信息的離散分配方式,提高內存的利用率,分頁僅僅是由於系統的需要而非用戶的需要。頁的大小是固定的,把邏輯地址分為頁號和頁內地址,但是用戶只用提供一個邏輯地址就能標識對應的地址,所以分頁作業地址空間是一維的。
段是信息的邏輯單位,它包含了一組意義相對完整的信息,長度可變,由用戶決定,程序員標識一個地址時,要給出段號還有段內偏移量,所以分段的作業地址空間是二維的。
3.進程通信方式?
1)匿名管道:通常稱為管道,管道是IPC最基本的一種實現機制,在Linux下一切皆文件,其實這里的管道就是一個文件。管道實現進程的通信就是讓兩個進程都能訪問這個文件。管道的特點只提供單向通信,雖然兩個進程都能訪問這個文件,但是一個在寫的時候另一個只能讀。同時只能用於具有血緣關系的進程之間通信,常用於父子進程通信。
2)FIFO命名管道:管道雖然實現了進程通信,但是也存在一定局限性,故提出了命名管道。其特點是提供了一個路徑名與之關聯,以FIFO文件的形式存儲在文件系統中,它不局限於父子進程,而能夠實現任意兩個進程之間的通信。同時遵循先進先出的原則,即第一個寫進的數據會第一個被讀走。
3)消息隊列:存放在內核中,在內核中創建一塊內存存放消息,生命周期隨內核,消息隊列會一直存在。同時可以雙向通信,不一定按照先進先出的方式取消息,也可以按照類型取消息。
4)信號量:類似於一個計數器,可以控制多個進程對共享資源的訪問,需要限制在同一時刻最大訪問資源的進程數。
5)共享內存:顧名思義,映射一段與其他進程共享的內存空間,當一個進程寫完后另一個進程讀就實現了進程通信,同時要注意寫的過程不能讀,這就需要配合信號量機制使用。共享內存區是IPC形式中最快的,因為進程不通過執行任何進入內核的系統調用就可以進行通信。
4.線程同步方式?
臨界區:訪問臨界資源的代碼段,在任意時刻只允許一個線程對臨界資源進行訪問,如果有多個線程試圖訪問臨界資源,那么在有一個線程進入后,其他試圖訪問臨界資源的線程將被掛起,並一直等到進入臨界區的線程離開,臨界區在被釋放后,其他線程才可以搶占。
互斥量:采用互斥對象機制,因為互斥對象只有一個,所以能保證公共資源不會同時被多個線程訪問。
信號量:同進程同步方式。
5.什么是線程安全?
指某個函數、函數庫在並發環境中被調用時,能后正確地處理多個線程之間的共享變量,是程序能夠正確的完成。
6.什么是死鎖?
在兩個或多個並發進程中,如果每個進程持有各自的資源而又都等待其余進程釋放正在持有的資源,在沒有外力的情況下誰都無法推進,相互等待的一種狀態,稱為死鎖。
7.死鎖產生的原因以及避免方法?
死鎖產生的原因1)系統資源的競爭:系統資源的競爭導致系統資源不足,以及資源分配不當,導致死鎖。2)進程運行推進順序不合適:進程在運行過程中,請求和釋放資源的順序不當,會導致死鎖。
死鎖產生的必要條件:1)互斥條件:一個資源每次只能被一個進程使用。2)請求與保持條件:進程已經保持了至少一個資源,但又提出了新的資源請求,但是請求的資源又正在被其他進程所占有。3)不可剝奪條件:進程所獲得的資源在未使用完畢之前,不能被其他進程強行奪走。4)循環等待條件:若干進程鍵形成首尾相連循環等待資源的關系。
死鎖避免方法:系統對進程發出的資源申請進行動態檢查,若分配后可能發生死鎖,那么不與分配,否則予以分配,這是一種保證系統不進入死鎖狀態的動態策略。如果操作系統能保證所有進程在有限時間內得到需要的全部資源,則系統處於安全狀態否則系統是不安全的。
8.操作系統的fork()過程?
父進程調用fork()函數后,系統給子進程分配資源時,fork並不直接復制父進程的內存空間,而是與父進程共享一個寫時復制的內存空間。Fork()返回時會返回兩次,分別返回到父進程和子進程。
9.說說Cpu調度算法?
1)先來先服務算法:按照進程就緒的先后順序使用處理器。
2)短作業優先算法:具有最短完成時間的進程優先使用處理器。
3)最高響應比優先算法:首先計算響應比,選擇最高響應比的進程使用處理器(響應比=(等待時間+處理時間)/處理時間)。
4)時間片輪轉調度算法:每個進程分配一個時間片,如果在時間片內沒有執行完畢則剝奪處理器並分配給其他進程。
5)最高優先級調度算法:選擇優先級最高的進程優先執行。優先級可以靜態不變,也可以動態調整。
6)多級反饋隊列調度算法:根據先來先服務原則給就緒隊列排序,為就緒隊列賦予不同的優先級數,不同的時間片,按照優先級搶占CPU的調度算法。
10.用戶態和內核態是什么?進程什么時候由用戶態轉化為內核態?
Linux進程地址空間分為用戶空間和內核空間,內核空間可以執行比用戶空間更高權限的動作。應用程序如果運行在用戶空間,就叫用戶態;如果運行在內核空間,就叫內核態。
系統調用:用戶進程主動要求切換到內核態的一種方式,用戶進程通過系統調用申請操作系統提供的程序服務完成工作,總是返回接着執行下一條指令。
異常:當CPU在執行運行在用戶態的程序時,出現了某些異常,這時會出發異常處理程序,由用戶態切換到內核態中,可能會返回到用戶態接着執行出現異常的指令,也可能直接終止而不返回。
中斷:當外圍設備准備完成之后,會向用戶發送相應的中斷信號,這時用戶在執行完當前指令后注意到中斷引腳的電壓變高了,就從系統總線讀取異常信號,然后調用適當的中斷處理程序。如果先執行的指令是在用戶態下那么自然就發生了用戶態到內核態的切換。
11.互斥量與信號量的區別?
互斥量用於線程的互斥,信號量用於線程的同步。
互斥量只能為0/1,信號量可以為非負值。
互斥量只能由一個線程加鎖或者解鎖,信號量可以由一個線程釋放,另一個線程得到。
12.進程切換會發生什么?
1)正在運行的用戶態進程X
2)發生中斷
3)保存現場
4)進程上下文切換
5)開始運行用戶態進程Y(這里Y曾經通過以上步驟被切換出去過因此可以繼續執行)
6)恢復現場
7)繼續運行用戶態進程Y
13.linux線程同步的方法?
互斥鎖(或稱互斥量Mutex),讀寫鎖(rdlock),條件變量(cond),信號量(Semophore)等。
14.互斥鎖、讀寫鎖和自旋鎖的區別和使用場景?
互斥鎖:保護了一個臨界區,在這個臨界區中,一次最多只能進入一個線程。
讀寫鎖:從廣義的邏輯上講,也可以認為是一種共享版的互斥鎖。可以多個線程同時進行讀,但是寫操作必須單獨進行,不可多寫和邊讀邊寫。如果對一個臨界區大部分是讀操作而只有少量的寫操作,讀寫鎖在一定程度上能夠降低線程互斥產生的代價。
自旋鎖:當要獲取一把自旋鎖的時候又被別的線程持有時,不斷循環的去檢索是否可以獲得自旋鎖,一直占CPU資源,直到獲取到鎖才會退出循環。
15.怎么解決死鎖?
發生死鎖后,撤銷進程,回收資源,分配給正在阻塞狀態的進程。
16.多進程和多線程那個更可靠?
多進程相比而言更可靠,因為多進程的進程之間不會互相影響,然而多線程一個線程崩潰會導致進程出錯使得進程中所有線程都出錯。
17.僵屍進程是什么,孤兒進程是什么?
子進程先於父進程結束,而父進程又沒有調用wait或者waitpid獲取其退出信息。子進程還需要在其PCB中保存其退出的相關信息,所以,子進程的執行主體已經結束,但是操作系統並沒有釋放該進程PCB結構,以滿足父進程后續對該子進程退出信息的查詢(如果父進程還在運行)。在子進程結束運行之后,父進程讀取其退出狀態之前,我們稱該子進程為僵屍進程。
父進程結束或者異常終止,但是子進程繼續運行。此時子進程的PPID被設置為1,即init進程。init進程接管了該子進程,並等待它結束,在父進程退出之后,子進程退出之前,該子進程屬於孤兒進程
18.進程上下文切換的過程?
(1接收到切換信號,掛起進程,記錄當前進程的虛擬內存、棧等資源存儲;
(2將這個進程在 CPU 中的上下文狀態存儲於起來;
(3然后在內存中檢索下一個進程的上下文;
(4並將其加載到 CPU的寄存器中恢復;
(5還需要刷新進程的虛擬內存和用戶棧;
(6最后跳轉到程序計數器所指向的位置(即跳轉到進程被中斷時的代碼行),以恢復該進程。
19.什么時候會發生進程調度?
1)進程時間片耗盡;
2)系統資源不足(如內存不足);
3)進程通過睡眠函數 sleep 把自己掛起來;
4)當有優先級更高的進程運行時,為了去運行高優先級進程,當前進程會被掛起;
5)發生硬中斷,CPU 上的進程會被掛起,然后去執行內核中的中斷服務進程。
20.進程切換的過程,線程呢?
1)切換頁目錄以使用新的地址空間。
2)保存當前執行進程的上下文。
3)使用進程調度算法,選擇一處於就緒狀態的進程。
4)恢復或裝配所選進程的上下文,將CPU控制權交到所選進程手中。
線程和進程的最大區別就在於地址空間,線程共享進程的地址空間,所以不會進行新的頁表的切換。
21.線程有什么是共享的什么是私有的?
線程共享的包括進程代碼段、進程的公有數據、進程打開的文件描述符、信號的處理器、進程當前目錄、進程用戶ID與進程組ID。
線程私有的有線程ID、寄存器組的值、線程的堆棧、錯誤返回碼、線程的信號屏蔽碼。