操作系統(tǒng)的四個(gè)特性?
并發(fā):同一段時(shí)間內(nèi)多個(gè)程序執(zhí)行(與并行區(qū)分,并行指的是同一時(shí)刻有多個(gè)事件,多處理器系統(tǒng)可以使程序并行執(zhí)行)
共享:系統(tǒng)中的資源可以被內(nèi)存中多個(gè)并發(fā)執(zhí)行的進(jìn)線程共同使用
虛擬:通過分時(shí)復(fù)用(如分時(shí)系統(tǒng))以及空分復(fù)用(如虛擬內(nèi)存)技術(shù)把一個(gè)物理實(shí)體虛擬為多個(gè)
異步:系統(tǒng)進(jìn)程用一種走走停停的方式執(zhí)行,(并不是一下子走完),進(jìn)程什么時(shí)候以怎樣的速度向前推進(jìn)是不可預(yù)知的
進(jìn)程線程
進(jìn)程是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序,每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間。
線程是比進(jìn)程更小的執(zhí)行單位,它是在一個(gè)進(jìn)程中獨(dú)立的控制流,一個(gè)進(jìn)程可以啟動(dòng)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)。
進(jìn)程和線程的區(qū)別如下:
- 調(diào)度:進(jìn)程是資源管理的基本單位,線程是程序執(zhí)行的基本單位。
- 切換:線程上下文切換比進(jìn)程上下文切換要快得多。
- 擁有資源: 進(jìn)程是擁有資源的一個(gè)獨(dú)立單位,線程不擁有系統(tǒng)資源,但是可以訪問隸屬于進(jìn)程的資源。
- 系統(tǒng)開銷: 創(chuàng)建或撤銷進(jìn)程時(shí),系統(tǒng)都要為之分配或回收系統(tǒng)資源,如內(nèi)存空間,I/O設(shè)備等,OS所付出的開銷顯著大于在創(chuàng)建或撤銷線程時(shí)的開銷,進(jìn)程切換的開銷也遠(yuǎn)大于線程切換的開銷。
本文已經(jīng)收錄到Github倉(cāng)庫(kù),該倉(cāng)庫(kù)包含計(jì)算機(jī)基礎(chǔ)、Java基礎(chǔ)、多線程、JVM、數(shù)據(jù)庫(kù)、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服務(wù)、設(shè)計(jì)模式、架構(gòu)、校招社招分享等核心知識(shí)點(diǎn),歡迎star~
Github地址
如果訪問不了Github,可以訪問gitee地址。
gitee地址
并發(fā)和并行
并發(fā)就是在一段時(shí)間內(nèi),多個(gè)任務(wù)都會(huì)被處理;但在某一時(shí)刻,只有一個(gè)任務(wù)在執(zhí)行。單核處理器可以做到并發(fā)。比如有兩個(gè)進(jìn)程A
和B
,A
運(yùn)行一個(gè)時(shí)間片之后,切換到B
,B
運(yùn)行一個(gè)時(shí)間片之后又切換到A
。因?yàn)榍袚Q速度足夠快,所以宏觀上表現(xiàn)為在一段時(shí)間內(nèi)能同時(shí)運(yùn)行多個(gè)程序。最全面的Java面試網(wǎng)站
并行就是在同一時(shí)刻,有多個(gè)任務(wù)在執(zhí)行。這個(gè)需要多核處理器才能完成,在微觀上就能同時(shí)執(zhí)行多條指令,不同的程序被放到不同的處理器上運(yùn)行,這個(gè)是物理上的多個(gè)進(jìn)程同時(shí)進(jìn)行。
多線程相較單線程的好處
1、并發(fā)提升程序執(zhí)行效率
2、提升CPU利用率,訪存的時(shí)候可以切換線程來執(zhí)行
3、更快的響應(yīng)速度,可以有專門的線程來監(jiān)聽用戶請(qǐng)求和專門的線程來處理請(qǐng)求。比如監(jiān)聽線程和工作線程是兩個(gè)線程,這樣監(jiān)聽就負(fù)責(zé)監(jiān)聽,工作的就負(fù)責(zé)工作,監(jiān)聽到用戶請(qǐng)求馬上把請(qǐng)求轉(zhuǎn)到工作線程去處理,監(jiān)聽線程繼續(xù)監(jiān)聽
什么是協(xié)程?
協(xié)程是一種用戶態(tài)的輕量級(jí)線程。
協(xié)程不是由操作系統(tǒng)內(nèi)核管理,而是完全由用戶程序所控制,這樣帶來的好處就是性能得到了很大的提升,不會(huì)像線程切換那樣消耗資源。
協(xié)程可以理解為可以暫停執(zhí)行的函數(shù)。它擁有自己的寄存器上下文和棧。協(xié)程調(diào)度切換時(shí),將寄存器上下文和棧保存到其他地方,在切回來的時(shí)候,恢復(fù)先前保存的寄存器上下文和棧,直接操作棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非???。
線程和協(xié)程有什么區(qū)別呢?
1、線程是搶占式,而協(xié)程是非搶占式的,所以需要用戶自己釋放使用權(quán)來切換到其他協(xié)程,因此同一時(shí)間其實(shí)只有一個(gè)協(xié)程擁有運(yùn)行權(quán),相當(dāng)于單線程的能力。
2、線程是協(xié)程的資源。協(xié)程通過 可以關(guān)聯(lián)任意線程或線程池的執(zhí)行器(Interceptor)來間接使用線程的資源的。
進(jìn)程通信
進(jìn)程間通信方式有以下幾種:
1、管道通信
匿名管道( pipe ):管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng),而且只能在具有親緣關(guān)系的進(jìn)程間使用。進(jìn)程的親緣關(guān)系通常是指父子進(jìn)程關(guān)系。
有名管道是半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng)。
2、消息隊(duì)列
3、共享內(nèi)存。共享內(nèi)存是最快的 IPC 方式,它是針對(duì)其他進(jìn)程間通信方式運(yùn)行效率低而專門設(shè)計(jì)的。它往往與其他通信機(jī)制,如信號(hào)量,配合使用,來實(shí)現(xiàn)進(jìn)程間的同步和通信。
4、信號(hào)量。信號(hào)量是一個(gè)計(jì)數(shù)器,可以用來控制多個(gè)進(jìn)程對(duì)共享資源的訪問。它常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問共享資源時(shí),其他進(jìn)程也訪問該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
什么是死鎖?
死鎖是指兩個(gè)或兩個(gè)以上的線程在執(zhí)行過程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象。若無外力作用,它們都將無法推進(jìn)下去。
如下圖所示,線程 A 持有資源 2,線程 B 持有資源 1,他們同時(shí)都想申請(qǐng)對(duì)方持有的資源,所以這兩個(gè)線程就會(huì)互相等待而進(jìn)入死鎖狀態(tài)。
下面通過例子說明線程死鎖,代碼來自并發(fā)編程之美。
最后給大家分享一個(gè)Github倉(cāng)庫(kù),上面有大彬整理的300多本經(jīng)典的計(jì)算機(jī)書籍PDF,包括C語言、C++、Java、Python、前端、數(shù)據(jù)庫(kù)、操作系統(tǒng)、計(jì)算機(jī)網(wǎng)絡(luò)、數(shù)據(jù)結(jié)構(gòu)和算法、機(jī)器學(xué)習(xí)、編程人生等,可以star一下,下次找書直接在上面搜索,倉(cāng)庫(kù)持續(xù)更新中~
Github地址
public class DeadLockDemo {
private static Object resource1 = new Object();//資源 1
private static Object resource2 = new Object();//資源 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "線程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "線程 2").start();
}
}
代碼輸出如下:
Thread[線程 1,5,main]get resource1
Thread[線程 2,5,main]get resource2
Thread[線程 1,5,main]waiting get resource2
Thread[線程 2,5,main]waiting get resource1
線程 A 通過 synchronized
(resource1) 獲得 resource1 的監(jiān)視器鎖,然后通過 Thread.sleep(1000)
。讓線程 A 休眠 1s 為的是讓線程 B 得到執(zhí)行然后獲取到 resource2 的監(jiān)視器鎖。線程 A 和線程 B 休眠結(jié)束了都開始企圖請(qǐng)求獲取對(duì)方的資源,然后這兩個(gè)線程就會(huì)陷入互相等待的狀態(tài),這也就產(chǎn)生了死鎖。
死鎖怎么產(chǎn)生?怎么避免?
死鎖產(chǎn)生的四個(gè)必要條件:
-
互斥:一個(gè)資源每次只能被一個(gè)進(jìn)程使用
-
請(qǐng)求與保持:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),不釋放獲得的資源
-
不剝奪:進(jìn)程已獲得的資源,在未使用之前,不能強(qiáng)行剝奪
-
循環(huán)等待:進(jìn)程之間循環(huán)等待著資源
避免死鎖的方法:
- 互斥條件不能破壞,因?yàn)榧渔i就是為了保證互斥
- 一次性申請(qǐng)所有的資源,避免線程占有資源而且在等待其他資源
- 占有部分資源的線程進(jìn)一步申請(qǐng)其他資源時(shí),如果申請(qǐng)不到,主動(dòng)釋放它占有的資源
- 按序申請(qǐng)資源
進(jìn)程調(diào)度策略有哪幾種?
-
先來先服務(wù):非搶占式的調(diào)度算法,按照請(qǐng)求的順序進(jìn)行調(diào)度。有利于長(zhǎng)作業(yè),但不利于短作業(yè),因?yàn)槎套鳂I(yè)必須一直等待前面的長(zhǎng)作業(yè)執(zhí)行完畢才能執(zhí)行,而長(zhǎng)作業(yè)又需要執(zhí)行很長(zhǎng)時(shí)間,造成了短作業(yè)等待時(shí)間過長(zhǎng)。另外,對(duì)
I/O
密集型進(jìn)程也不利,因?yàn)檫@種進(jìn)程每次進(jìn)行I/O
操作之后又得重新排隊(duì)。 -
短作業(yè)優(yōu)先:非搶占式的調(diào)度算法,按估計(jì)運(yùn)行時(shí)間最短的順序進(jìn)行調(diào)度。長(zhǎng)作業(yè)有可能會(huì)餓死,處于一直等待短作業(yè)執(zhí)行完畢的狀態(tài)。因?yàn)槿绻恢庇卸套鳂I(yè)到來,那么長(zhǎng)作業(yè)永遠(yuǎn)得不到調(diào)度。
-
最短剩余時(shí)間優(yōu)先:最短作業(yè)優(yōu)先的搶占式版本,按剩余運(yùn)行時(shí)間的順序進(jìn)行調(diào)度。 當(dāng)一個(gè)新的作業(yè)到達(dá)時(shí),其整個(gè)運(yùn)行時(shí)間與當(dāng)前進(jìn)程的剩余時(shí)間作比較。如果新的進(jìn)程需要的時(shí)間更少,則掛起當(dāng)前進(jìn)程,運(yùn)行新的進(jìn)程。否則新的進(jìn)程等待。
-
時(shí)間片輪轉(zhuǎn):將所有就緒進(jìn)程按
FCFS
的原則排成一個(gè)隊(duì)列,每次調(diào)度時(shí),把CPU
時(shí)間分配給隊(duì)首進(jìn)程,該進(jìn)程可以執(zhí)行一個(gè)時(shí)間片。當(dāng)時(shí)間片用完時(shí),由計(jì)時(shí)器發(fā)出時(shí)鐘中斷,調(diào)度程序便停止該進(jìn)程的執(zhí)行,并將它送往就緒隊(duì)列的末尾,同時(shí)繼續(xù)把CPU
時(shí)間分配給隊(duì)首的進(jìn)程。時(shí)間片輪轉(zhuǎn)算法的效率和時(shí)間片的大小有很大關(guān)系:因?yàn)檫M(jìn)程切換都要保存進(jìn)程的信息并且載入新進(jìn)程的信息,如果時(shí)間片太小,會(huì)導(dǎo)致進(jìn)程切換得太頻繁,在進(jìn)程切換上就會(huì)花過多時(shí)間。 而如果時(shí)間片過長(zhǎng),那么實(shí)時(shí)性就不能得到保證。
-
優(yōu)先級(jí)調(diào)度:為每個(gè)進(jìn)程分配一個(gè)優(yōu)先級(jí),按優(yōu)先級(jí)進(jìn)行調(diào)度。為了防止低優(yōu)先級(jí)的進(jìn)程永遠(yuǎn)等不到調(diào)度,可以隨著時(shí)間的推移增加等待進(jìn)程的優(yōu)先級(jí)。
進(jìn)程有哪些狀態(tài)?
進(jìn)程一共有5
種狀態(tài),分別是創(chuàng)建、就緒、運(yùn)行(執(zhí)行)、終止、阻塞。
- 運(yùn)行狀態(tài)就是進(jìn)程正在
CPU
上運(yùn)行。在單處理機(jī)環(huán)境下,每一時(shí)刻最多只有一個(gè)進(jìn)程處于運(yùn)行狀態(tài)。 - 就緒狀態(tài)就是說進(jìn)程已處于準(zhǔn)備運(yùn)行的狀態(tài),即進(jìn)程獲得了除
CPU
之外的一切所需資源,一旦得到CPU
即可運(yùn)行。 - 阻塞狀態(tài)就是進(jìn)程正在等待某一事件而暫停運(yùn)行,比如等待某資源為可用或等待
I/O
完成。即使CPU
空閑,該進(jìn)程也不能運(yùn)行。
運(yùn)行態(tài)→阻塞態(tài):往往是由于等待外設(shè),等待主存等資源分配或等待人工干預(yù)而引起的。
阻塞態(tài)→就緒態(tài):則是等待的條件已滿足,只需分配到處理器后就能運(yùn)行。
運(yùn)行態(tài)→就緒態(tài):不是由于自身原因,而是由外界原因使運(yùn)行狀態(tài)的進(jìn)程讓出處理器,這時(shí)候就變成就緒態(tài)。例如時(shí)間片用完,或有更高優(yōu)先級(jí)的進(jìn)程來搶占處理器等。
就緒態(tài)→運(yùn)行態(tài):系統(tǒng)按某種策略選中就緒隊(duì)列中的一個(gè)進(jìn)程占用處理器,此時(shí)就變成了運(yùn)行態(tài)。
操作系統(tǒng)里的內(nèi)存碎片怎么理解?
內(nèi)存碎片通常分為內(nèi)部碎片和外部碎片:
- 內(nèi)部碎片是由于采用固定大小的內(nèi)存分區(qū),當(dāng)一個(gè)進(jìn)程不能完全使用分給它的固定內(nèi)存區(qū)域時(shí)就會(huì)產(chǎn)生內(nèi)部碎片。通常內(nèi)部碎片難以完全避免
- 外部碎片是由于某些未分配的連續(xù)內(nèi)存區(qū)域太小,以至于不能滿足任意進(jìn)程的內(nèi)存分配請(qǐng)求,從而不能被進(jìn)程利用的內(nèi)存區(qū)域。
有什么解決辦法?
現(xiàn)在普遍采取的內(nèi)存分配方式是段頁式內(nèi)存分配。將內(nèi)存分為不同的段,再將每一段分成固定大小的頁。通過頁表機(jī)制,使段內(nèi)的頁可以不必連續(xù)處于同一內(nèi)存區(qū)域。
虛擬內(nèi)存
虛擬存儲(chǔ)器就是具有請(qǐng)求調(diào)入功能,能從邏輯上對(duì)內(nèi)存容量加以擴(kuò)充的一種存儲(chǔ)器系統(tǒng),虛擬內(nèi)存有多次性,對(duì)換性和虛擬性三個(gè)特征,它可以將程序分多次調(diào)入內(nèi)存,使得在較小的用戶空間可以執(zhí)行較大的用戶程序,所以同時(shí)容納更多的進(jìn)程并發(fā)執(zhí)行,從而提高系統(tǒng)的吞吐量。發(fā)生缺頁時(shí)可以調(diào)入一個(gè)段也可以調(diào)入一個(gè)頁,取決于內(nèi)存的存儲(chǔ)管理方式。虛擬性表示虛擬內(nèi)存和物理內(nèi)存的映射。
Linux下,進(jìn)程不能直接讀寫內(nèi)存物理地址,只能訪問【虛擬內(nèi)存地址】。操作系統(tǒng)會(huì)把虛擬內(nèi)存地址-->物理地址。
虛擬內(nèi)存解決有限的內(nèi)存空間加載較大應(yīng)用程序的問題,根據(jù)需要在內(nèi)存和磁盤之間來回傳送數(shù)據(jù)。
通過段頁表的形式,虛擬內(nèi)存中取一段連續(xù)的內(nèi)存空間映射到主內(nèi)存中,主內(nèi)存空間的程序段可以不連續(xù) 。
什么是分頁?
把內(nèi)存空間劃分為大小相等且固定的塊,作為主存的基本單位。因?yàn)槌绦驍?shù)據(jù)存儲(chǔ)在不同的頁面中,而頁面又離散的分布在內(nèi)存中,因此需要一個(gè)頁表來記錄映射關(guān)系,以實(shí)現(xiàn)從頁號(hào)到物理塊號(hào)的映射。
訪問分頁系統(tǒng)中內(nèi)存數(shù)據(jù)需要兩次的內(nèi)存訪問 (一次是從內(nèi)存中訪問頁表,從中找到指定的物理塊號(hào),加上頁內(nèi)偏移得到實(shí)際物理地址;第二次就是根據(jù)第一次得到的物理地址訪問內(nèi)存取出數(shù)據(jù))。
什么是分段?
分頁是為了提高內(nèi)存利用率,而分段是為了滿足程序員在編寫代碼的時(shí)候的一些邏輯需求(比如數(shù)據(jù)共享,數(shù)據(jù)保護(hù),動(dòng)態(tài)鏈接等)。
分段內(nèi)存管理當(dāng)中,地址是二維的,一維是段號(hào),二維是段內(nèi)地址;其中每個(gè)段的長(zhǎng)度是不一樣的,而且每個(gè)段內(nèi)部都是從0開始編址的。由于分段管理中,每個(gè)段內(nèi)部是連續(xù)內(nèi)存分配,但是段和段之間是離散分配的,因此也存在一個(gè)邏輯地址到物理地址的映射關(guān)系,相應(yīng)的就是段表機(jī)制。
分頁和分段有什區(qū)別?
- 分頁對(duì)程序員是透明的,但是分段需要程序員顯式劃分每個(gè)段。
- 分頁的地址空間是一維地址空間,分段是二維的。
- 頁的大小不可變,段的大小可以動(dòng)態(tài)改變。
- 分頁主要用于實(shí)現(xiàn)虛擬內(nèi)存,從而獲得更大的地址空間;分段主要是為了使程序和數(shù)據(jù)可以被劃分為邏輯上獨(dú)立的地址空間并且有助于共享和保護(hù)。
頁面置換算法
為什么要頁面置換:
因?yàn)閼?yīng)用程序是分多次裝入內(nèi)存的,所以運(yùn)行到一定的時(shí)間,一定會(huì)發(fā)生缺頁。地址映射的過程中,如果頁面中發(fā)現(xiàn)要訪問的頁面不在內(nèi)存中,會(huì)產(chǎn)生缺頁中斷。此時(shí)操作系統(tǒng)必須在內(nèi)存里選擇一個(gè)頁面把他移出內(nèi)存,為即將調(diào)入的頁面讓出空間。選擇淘汰哪一頁的規(guī)則就是頁面置換算法
幾種頁面置換算法:
最佳置換算法(理想):將當(dāng)前頁面中在未來最長(zhǎng)時(shí)間內(nèi)不會(huì)被訪問的頁置換出去
先進(jìn)先出:淘汰最早調(diào)入的頁面
最近最久未使用 LRU:每個(gè)頁面有一個(gè)t來記錄上次頁面被訪問直到現(xiàn)在,每次置換時(shí)置換t值最大的頁面(用寄存器或棧實(shí)現(xiàn))
時(shí)鐘算法clock(也被稱為最近未使用算法NRU):頁面設(shè)置訪問為,將頁面鏈接為一個(gè)環(huán)形列表,每個(gè)頁有一個(gè)訪問位0/1, 1表示又一次獲救的機(jī)會(huì),下次循環(huán)指針指向它時(shí)可以免除此次置換,但是會(huì)把訪問位置為0, 代表他下次如果碰到循環(huán)指針就該被置換了。頁面被訪問的時(shí)候訪問位設(shè)為1。頁面置換的時(shí)候,如果當(dāng)前指針的訪問位為0,置換,否則將這個(gè)值置為0,循環(huán)直到遇到訪問位為0的頁面。
改進(jìn)型Clock算法:在clock算法的基礎(chǔ)上添加一個(gè)修改位,優(yōu)先替換訪問位和修改位都是0的頁面,其次替換訪問位為0修改位為1的頁面。
最少使用算法LFU:設(shè)置寄存器記錄頁面被訪問次數(shù),每次置換當(dāng)前訪問次數(shù)最少的。
用戶態(tài)和內(nèi)核態(tài)
內(nèi)核態(tài):cpu可以訪問內(nèi)存的所有數(shù)據(jù),包括外圍設(shè)備,例如硬盤,網(wǎng)卡,cpu也可以將自己從一個(gè)程序切換到另一個(gè)程序。
用戶態(tài):只能受限的訪問內(nèi)存,且不允許訪問外圍設(shè)備,占用cpu的能力被剝奪,cpu資源可以被其他程序獲取。
最大的區(qū)別就是權(quán)限不同,在運(yùn)行在用戶態(tài)下的程序不能直接訪問操作系統(tǒng)內(nèi)核數(shù)據(jù)結(jié)構(gòu)和程序。
為什么要有這兩種狀態(tài)?
內(nèi)核速度快但是資源有限,能控制的進(jìn)程數(shù)不多,所以需要速度慢一些的用戶態(tài)協(xié)助,但是為了避免用戶態(tài)被惡意利用,所以限制了用戶態(tài)程序的權(quán)限。
需要限制不同的程序之間的訪問能力,防止他們獲取別的程序的內(nèi)存數(shù)據(jù),或者獲取外圍設(shè)備的數(shù)據(jù),并發(fā)送到網(wǎng)絡(luò),CPU劃分出兩個(gè)權(quán)限等級(jí) -- 用戶態(tài)和內(nèi)核態(tài)。
什么時(shí)候轉(zhuǎn)換
1、系統(tǒng)調(diào)用:
用戶進(jìn)程主動(dòng)發(fā)起的。用戶態(tài)進(jìn)程通過系統(tǒng)調(diào)用申請(qǐng)使用操作系統(tǒng)提供的服務(wù)程序完成工作,比如fork()就是執(zhí)行一個(gè)創(chuàng)建新進(jìn)程的系統(tǒng)調(diào)用
用戶程序使用系統(tǒng)調(diào)用,系統(tǒng)調(diào)用會(huì)轉(zhuǎn)換為內(nèi)核態(tài)并調(diào)用操作系統(tǒng)
2、發(fā)生異常:
會(huì)從當(dāng)前運(yùn)行進(jìn)程切換到處理次此異常的內(nèi)核相關(guān)程序中
3、外圍設(shè)備的中斷:
所有程序都運(yùn)行在用戶態(tài),但在從硬盤讀取數(shù)據(jù)、或從鍵盤輸入時(shí),這些事情只有操作系統(tǒng)能做,程序需要向操作系統(tǒng)請(qǐng)求以程序的名義來執(zhí)行這些操作。這個(gè)時(shí)候用戶態(tài)程序切換到內(nèi)核態(tài)。
什么是緩沖區(qū)溢出?有什么危害?
緩沖區(qū)溢出是指當(dāng)計(jì)算機(jī)向緩沖區(qū)填充數(shù)據(jù)時(shí)超出了緩沖區(qū)本身的容量,溢出的數(shù)據(jù)覆蓋在合法數(shù)據(jù)上。
危害有以下兩點(diǎn):
- 程序崩潰,導(dǎo)致拒絕額服務(wù)
- 跳轉(zhuǎn)并且執(zhí)行一段惡意代碼
造成緩沖區(qū)溢出的主要原因是程序中沒有仔細(xì)檢查用戶輸入。文章來源:http://www.zghlxwxcb.cn/news/detail-414263.html
IO多路復(fù)用
IO多路復(fù)用是指內(nèi)核一旦發(fā)現(xiàn)進(jìn)程指定的一個(gè)或者多個(gè)IO條件準(zhǔn)備讀取,它就通知該進(jìn)程。IO多路復(fù)用適用如下場(chǎng)合:文章來源地址http://www.zghlxwxcb.cn/news/detail-414263.html
- 當(dāng)客戶處理多個(gè)描述字時(shí)(一般是交互式輸入和網(wǎng)絡(luò)套接口),必須使用I/O復(fù)用。
- 當(dāng)一個(gè)客戶同時(shí)處理多個(gè)套接口時(shí),而這種情況是可能的,但很少出現(xiàn)。
- 如果一個(gè)TCP服務(wù)器既要處理監(jiān)聽套接口,又要處理已連接套接口,一般也要用到I/O復(fù)用。
- 如果一個(gè)服務(wù)器即要處理TCP,又要處理UDP,一般要使用I/O復(fù)用。
- 如果一個(gè)服務(wù)器要處理多個(gè)服務(wù)或多個(gè)協(xié)議,一般要使用I/O復(fù)用。
- 與多進(jìn)程和多線程技術(shù)相比,I/O多路復(fù)用技術(shù)的最大優(yōu)勢(shì)是系統(tǒng)開銷小,系統(tǒng)不必創(chuàng)建進(jìn)程/線程,也不必維護(hù)這些進(jìn)程/線程,從而大大減小了系統(tǒng)的開銷。
到了這里,關(guān)于一天吃透操作系統(tǒng)八股文的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!