當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序喵大人
[導(dǎo)讀]面試的過(guò)程中,為了考察面試者的基礎(chǔ)功力,除了算法以外,操作系統(tǒng)將會(huì)占比很大的權(quán)重,本文給大家分享我在面試過(guò)程中出現(xiàn)的非常高頻的面試題,我基本上會(huì)從兩個(gè)角度來(lái)闡述,一個(gè)是"官話",一個(gè)是“大白話”。希望對(duì)即將面試的你有所幫助。

面試的過(guò)程中,為了考察面試者的基礎(chǔ)功力,除了算法以外,操作系統(tǒng)將會(huì)占比很大的權(quán)重,本文給大家分享我在面試過(guò)程中出現(xiàn)的非常高頻的面試題,我基本上會(huì)從兩個(gè)角度來(lái)闡述,一個(gè)是"官話",一個(gè)是“大白話”。希望對(duì)即將面試的你有所幫助

提綱

1、為什么有了進(jìn)程,還要有線程呢?

為了提高系統(tǒng)資源的利用率和系統(tǒng)的吞吐量,通常進(jìn)程可讓多個(gè)程序并發(fā)的執(zhí)行,但是也會(huì)帶來(lái)一些問(wèn)題

官話

  • 進(jìn)程如果在執(zhí)行的過(guò)程被阻塞,那這個(gè)進(jìn)程將被掛起,這時(shí)候進(jìn)程中有些等待的資源得不到執(zhí)行:

  • 進(jìn)程在同一時(shí)間只能做一件事兒

基于以上的缺點(diǎn),操作系統(tǒng)引入了比進(jìn)程粒度更小的線程,作為并發(fā)執(zhí)行的基本單位,從而減少程序在并發(fā)執(zhí)行時(shí)所付出的時(shí)間和空間開銷,提高并發(fā)性能。

舉個(gè)例子

小Q當(dāng)年開發(fā)了一個(gè)聊天軟件,給女朋友說(shuō):咋們以后不用什么qq,微信了,我寫個(gè)聊天工具,咱兩正兒八經(jīng)的兩人世界可好。

說(shuō)干就干,小Q很快就完成了開發(fā),然后開始測(cè)試,打電話讓女朋友讓她發(fā)個(gè)信息,小Q就等著,等啊等啊,怎么還沒(méi)有發(fā)信息過(guò)來(lái),沒(méi)顯示啊,一臉懵逼,單步調(diào)試吧,發(fā)現(xiàn)程序卡在了wati for user input不動(dòng)了。牛逼,程序不輸入就沒(méi)辦法執(zhí)行后面的任務(wù)。咋搞?要不設(shè)置個(gè)1s,用戶1s不輸入直接跳過(guò)進(jìn)行后面的接收階段顯示階段,牛皮牛皮,果然好使,好使個(gè)錘錘,這樣用戶輸入信息不就很可能丟失,咋搞?

能不能將輸入和顯示這兩個(gè)動(dòng)作給分開,一個(gè)負(fù)責(zé)輸入,發(fā)送消息,一個(gè)負(fù)責(zé)讀信息和顯示。不夸夸你自己?jiǎn)?,直接開干呈現(xiàn)兩個(gè)窗口。

回來(lái)回來(lái),這就是我們的多進(jìn)程。不過(guò)多進(jìn)程也還是有些問(wèn)題需要注意,開多個(gè)窗口沒(méi)問(wèn)題,無(wú)腦開窗口撩騷直接被榨干(內(nèi)存耗盡),而且想要幾個(gè)窗口交換個(gè)數(shù)據(jù)也是賊麻煩,這是為啥呢

多進(jìn)程的程序,每個(gè)進(jìn)程都有自己的獨(dú)立內(nèi)存空間,都穿了衣服,不能相互亂看,要想通信就要接觸系統(tǒng)層面來(lái)通信,所以肯定就會(huì)造成較多的資源消耗和時(shí)間浪費(fèi)。怎么整?

幾個(gè)進(jìn)程為了方便,干脆商量一波,能不能開辟一塊內(nèi)存空間,共樂(lè)其中,這就是線程非常重要的意義,不過(guò)共享了不代表我們就是""的,個(gè)人保密還是要做到,也不要吵架,可不可以通過(guò)鎖的方式保密呢,這就涉及到了線程的同步。這樣我猜測(cè)你應(yīng)該了解進(jìn)程和線程了吧。

2、簡(jiǎn)單說(shuō)下你對(duì)并發(fā)和并行的理解?

官話從概念出發(fā):

  • 并發(fā)

在一個(gè)時(shí)間段中多個(gè)程序都啟動(dòng)運(yùn)行在同一個(gè)處理機(jī)中

  • 并行

假設(shè)目前A,B兩個(gè)進(jìn)程,兩個(gè)進(jìn)程分別由不同的 CPU ?管理執(zhí)行,兩個(gè)進(jìn)程不搶占 CPU ?資源且可以同時(shí)運(yùn)行,這叫做并行。

例子

并發(fā)是指多個(gè)任務(wù)在一段時(shí)間內(nèi)發(fā)生。比如今日成都某家老火鍋店做活動(dòng),全場(chǎng)5折(這還是比較狠),但是只有200個(gè)位置,但是來(lái)的人太多了,來(lái)了250個(gè)人,此時(shí)多出的50個(gè)人只好等待著或者去另外家火鍋店。那么火鍋店老板對(duì)這250的安排不是同一時(shí)刻安排而是一段時(shí)間去處理,其實(shí)這就是并發(fā)。這個(gè)例子好像整的不算生動(dòng),我們?cè)賮?lái)一個(gè)

到了周末就是我們"開黑"的時(shí)光,奈何到了周一不遲到怎么對(duì)得起自己,但是遲到了被逮住就要被"BB"。好嘛,我們作為學(xué)生娃兒只好認(rèn)慫,常規(guī)操作,兩腳一,起床,刷牙,上廁所,拿包包。就是這樣類似復(fù)讀機(jī)的習(xí)慣操作是怎么回事?莫非我們就能同時(shí)干這么多事?其實(shí)不是的,我們大腦下達(dá)指令,起床,刷牙這些操作早形成了肌肉記憶,所以我們?cè)谶@小段時(shí)間完成了這么多事兒,還可以多幾分鐘出來(lái)看看美女不香?

并發(fā)

平時(shí)玩兒電腦的時(shí)候,邊寫代碼邊聽音樂(lè),計(jì)算機(jī)同時(shí)處理了這么多任務(wù)。如果是單核 CPU ?,在我們看來(lái)這些事兒是同時(shí)發(fā)生的,其實(shí)那是因?yàn)榈讓?CPU ?切換的速度太快以致于我們完全感受不到它的切換,僅此為錯(cuò)覺(jué)而已。但是如果是多核 ?CPU ? ?,各個(gè) CPU ?負(fù)責(zé)不同的進(jìn)程,各個(gè)進(jìn)程不搶占 CPU ?,這樣同時(shí)進(jìn)行,這就是真正意義上的并行

并行

說(shuō)了這么多,那并行和并發(fā)到底啥區(qū)別?

兩者區(qū)別在于是否"同時(shí)"發(fā)生。是在一段時(shí)間同時(shí)發(fā)生還是多個(gè)事情在同一個(gè)時(shí)間點(diǎn)同時(shí)發(fā)生。

3、同步、異步、阻塞、非阻塞的概念

首先大家應(yīng)該知道同步異步,阻塞非阻塞是兩個(gè)不同層面的問(wèn)題,一個(gè)是operation層面,一個(gè)是kernal層面。同步異步最大的區(qū)別在于是否需要底層的響應(yīng)再執(zhí)行。阻塞非阻塞最大的區(qū)別在于是否立即給出響應(yīng)。

官話

同步:當(dāng)一個(gè)同步調(diào)用發(fā)出后,調(diào)用者要一直等待返回結(jié)果。通知后,才能進(jìn)行后續(xù)的執(zhí)行。

異步:當(dāng)一個(gè)異步過(guò)程調(diào)用發(fā)出后,調(diào)用者不能立刻得到返回結(jié)果。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過(guò)狀態(tài)、通知和回調(diào)來(lái)通知調(diào)用者。

阻塞:是指調(diào)用結(jié)果返回前,當(dāng)前線程會(huì)被掛起,即阻塞。

非阻塞:是指即使調(diào)用結(jié)果沒(méi)返回,也不會(huì)阻塞當(dāng)前線程。

形象比喻

  • 小Q去釣魚,拋完線后就傻傻的看著有沒(méi)有動(dòng)靜,有則拉桿(同步阻塞)

  • 小Q去釣魚,拿魚網(wǎng)撈一下,有沒(méi)有魚立即知道,不用等,直接就撈(同步非阻塞)

  • 小Q去釣魚,這個(gè)魚缸比較牛皮,扔了后自己就打王者榮耀去了,因?yàn)轸~上鉤了這個(gè)魚缸帶的報(bào)警器會(huì)通知我。這樣實(shí)現(xiàn)異步(異步非阻塞)

4、進(jìn)程和線程的相關(guān)題

官話

  • 進(jìn)程:進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位,是系統(tǒng)中的并發(fā)執(zhí)行的單位。

  • 線程:線程是進(jìn)程的一個(gè)實(shí)體,也是 ?CPU ? 調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位,有時(shí)又被稱為輕量級(jí)進(jìn)程。

  • 進(jìn)程是資源分配的最小單位,而線程是 ** CPU ? 調(diào)度**的最小單位;

  • 創(chuàng)建進(jìn)程或撤銷進(jìn)程,系統(tǒng)都要為之分配或回收資源,操作系統(tǒng)開銷遠(yuǎn)大于創(chuàng)建或撤銷線程時(shí)的開銷;

  • 不同進(jìn)程地址空間相互獨(dú)立,同一進(jìn)程內(nèi)的線程共享同一地址空間。一個(gè)進(jìn)程的線程在另一個(gè)進(jìn)程內(nèi)是不可見(jiàn)的;

  • 進(jìn)程間不會(huì)相互影響,而一個(gè)線程掛掉將可能導(dǎo)致整個(gè)進(jìn)程掛掉;

別背了,我知道你們都會(huì)背,舉個(gè)例子

計(jì)算機(jī)中的核心是 CPU ?,說(shuō)它是我們的大腦一點(diǎn)不為過(guò)。在此用一個(gè)連鎖火鍋店舉例,因?yàn)橐咔榈挠绊?,今天到目前營(yíng)業(yè)額一般,只好開一家店,其他疫情較為嚴(yán)重的店只好先關(guān)閉,這里涉及的含義:?jiǎn)蝹€(gè) CPU ?一次只運(yùn)行一個(gè)任務(wù)。進(jìn)程就類似這家火鍋店,它代表 CPU ?所能處理的單個(gè)任務(wù),其他地方火鍋店只能處于非運(yùn)行狀態(tài)。

一個(gè)火鍋店有很多服務(wù)員,一起協(xié)同工作,將火鍋店做的紅紅火火,那么線程就好比這些服務(wù)員,一個(gè)進(jìn)程可有多個(gè)線程。、

火鍋店各個(gè)工作房間是共享的,所有服務(wù)員都可以進(jìn)出,這意味著進(jìn)程的內(nèi)存空間共享,每個(gè)線程都可以使用這些共享內(nèi)存。但是不是每個(gè)房間都可以容納相同的人數(shù),比如衛(wèi)生間就只有一個(gè)人,其他人不能同時(shí)進(jìn)去。這意味著一個(gè)線程在使用共享內(nèi)存的時(shí)候,其他線程需要等待結(jié)束才能使用這塊內(nèi)存。那怎么防止別人進(jìn)入呢?很直接的辦法就是進(jìn)去之后記得關(guān)門(上鎖),上了鎖,其他人想進(jìn)來(lái)發(fā)現(xiàn)是上鎖了,那就等鎖打開后再進(jìn)去,這就叫做互斥鎖,防止多個(gè)線程同時(shí)讀寫某一塊內(nèi)存區(qū)域。

ok到這里,我們總結(jié)一波

  • 如果以多進(jìn)程的方式運(yùn)行,那么允許多個(gè)任務(wù)同時(shí)運(yùn)行

  • 如果以多線程的方式運(yùn)行,那么允許將單個(gè)任務(wù)分成不同的部分運(yùn)行

  • 為了防止進(jìn)程/線程之間產(chǎn)生沖突和允許進(jìn)程之間的共享資源,需要提供一種協(xié)調(diào)機(jī)制。

多線程與多進(jìn)程的基本概念

不知道大家經(jīng)歷過(guò)食堂打菜的場(chǎng)景沒(méi)有,如果學(xué)校食堂就開設(shè)一個(gè)窗口,打菜的阿姨也沒(méi)辦法,只好一個(gè)個(gè)給大家依次打菜,這就好比"單線程",效率非常低(此處可以考慮為什么redis使用單線程卻這么牛逼)

為了提高效率,在食堂多加了幾個(gè)窗口,這就類似"多線程"形式。

那么又想起一個(gè)問(wèn)題,“多線程一定就比單線程效率高麥?”(ps Memcache是多線程模型而Redis是單線程模型)

貌似我們一提到高并發(fā),分布式,就不得不想起多線程,那么多線程一定比單線程效率高?

上面說(shuō)了采用多線程多核效果更好,但是多線程對(duì) CPU ?,內(nèi)存等都要求比較高,如果存在的上下文切換過(guò)于耗時(shí),互斥時(shí)間太久,效率反而會(huì)低。

不一定。我不從專業(yè)術(shù)語(yǔ)來(lái)將,舉個(gè)例子,假設(shè)目前接水房有四個(gè)水管可以接水,我如果用4個(gè)桶分別對(duì)應(yīng)4個(gè)水管,那么就比較完美,如果少一個(gè)則閑置一個(gè),多一個(gè)則會(huì)出現(xiàn)搶占。如果此時(shí)我的水桶個(gè)數(shù)大于水管數(shù),為了每個(gè)桶都有水,我們就需要切換水桶,這個(gè)過(guò)程實(shí)際上就是線程的上下文切換,代價(jià)一樣不小。

多線程與多進(jìn)程的應(yīng)用場(chǎng)景

多線程的優(yōu)點(diǎn)

  • 更加高效的內(nèi)存共享。多進(jìn)程下內(nèi)存共享不便

  • 較輕的上下文切換。因?yàn)椴挥们袚Q地址空間,CR3寄存器和清空TLB

多進(jìn)程的優(yōu)點(diǎn):

  • 各個(gè)進(jìn)程有自己內(nèi)存空間,所以具有更強(qiáng)的容錯(cuò)性,不至于一個(gè)集成crash導(dǎo)致系統(tǒng)崩潰

  • 具有更好的多核可伸縮性,因?yàn)檫M(jìn)程將地址空間,頁(yè)表等進(jìn)行了隔離,在多核的系統(tǒng)上可伸縮性更強(qiáng)

如何提升多線程的效率

  • 盡量使用池化技術(shù),也就是線程池,從而不用頻繁的創(chuàng)建,銷毀線程

  • 減少線程之間的同步和通信

  • 通過(guò)Huge Page的方式避免產(chǎn)生大量的缺頁(yè)異常

  • 避免需要頻繁共享寫的數(shù)據(jù)

5、進(jìn)程的狀態(tài)轉(zhuǎn)換

在Linux中,進(jìn)程的狀態(tài)有七種

  • 可運(yùn)行狀態(tài)

英文名詞為TASK_RUNNING,其實(shí)這個(gè)狀態(tài)雖然是RUNING,實(shí)際上并不一定會(huì)占有 CPU ?,可能修改TASK_RUNABLE會(huì)更妥當(dāng)。TASK_RUNGING根據(jù)是否在在 CPU ?上運(yùn)行分為RUNGING和READY兩種狀態(tài)。處于READY狀態(tài)的進(jìn)程隨時(shí)可以運(yùn)行,只不過(guò)因?yàn)榇藭r(shí) CPU ?資源受限,調(diào)度器沒(méi)選中運(yùn)行

可運(yùn)行狀態(tài)
  • 可中斷睡眠狀態(tài)與不可中斷睡眠狀態(tài)

我們知道進(jìn)程不可能一直處于可運(yùn)行的狀態(tài)。假設(shè)A進(jìn)程需要讀取磁盤中的文件,這樣的系統(tǒng)調(diào)用消耗時(shí)間較長(zhǎng),進(jìn)程需要等待較長(zhǎng)的時(shí)間才能執(zhí)行后面的命令,而且等待的時(shí)間還是不可估算的,這樣的話進(jìn)程還占用 CPU ?就不友好了,因此內(nèi)核就會(huì)將其更改為其他的狀態(tài)并從 CPU ?可運(yùn)行的隊(duì)列移除。

Linux中存在兩種睡眠狀態(tài),分別為:可中斷的睡眠狀態(tài)和不可中斷的狀態(tài)。兩者最大的區(qū)別為是否響應(yīng)收到的信號(hào),那么從可中斷的睡眠的進(jìn)程是如何返回到可運(yùn)行的狀態(tài)呢

  • 等待的事情發(fā)生且繼續(xù)運(yùn)行的條件滿足

  • 收到了沒(méi)有被屏蔽的信號(hào)

處于此狀態(tài)的進(jìn)程,收到信號(hào)會(huì)返回EINTR給用戶空間。開發(fā)者通過(guò)檢測(cè)返回值的方式進(jìn)行后續(xù)邏輯處理

但是對(duì)于不可中斷的睡眠狀態(tài),就只有一種方式返回到可運(yùn)行狀態(tài),即等待事情發(fā)生了繼續(xù)運(yùn)行

上圖中為什么出現(xiàn)個(gè) TASK_UNINTERRUPTIBLE 狀態(tài),主要是因?yàn)閮?nèi)核中的進(jìn)程不是什么進(jìn)程都可以被打斷,假設(shè)響應(yīng)的是異步信號(hào),程序在執(zhí)行的過(guò)程中插入一段用于處理異步信號(hào)的而流程,原來(lái)的流程就會(huì)被中斷。所以當(dāng)進(jìn)程在和硬件打交道的時(shí)候,需要使用 TASK_UNINTERRUPTIBLE 狀態(tài)將進(jìn)程保護(hù)起來(lái),從而避免進(jìn)程和設(shè)備打交道的過(guò)程中被打斷導(dǎo)致設(shè)備處于不可控的狀態(tài)。

那么TASK_UNINTERRUPTIBLE狀態(tài)會(huì)出現(xiàn)多久呢?

其實(shí) TASK_UNINTERRUPTIBLE 狀態(tài)是很危險(xiǎn)的狀態(tài),因?yàn)樗稑尣蝗耄銦o(wú)法通過(guò)信號(hào)殺死這樣一個(gè)不可中斷的休眠狀態(tài),正常情況,TASK_UNINTERRUPTIBLE狀態(tài)存在時(shí)間很短,但是不排除存在此狀態(tài)進(jìn)程比較持久的情況,真的刀槍不入了?可不可以進(jìn)行提前的預(yù)防?

可以的,早就考慮了。內(nèi)核提供了hung task機(jī)制,它會(huì)啟動(dòng)一個(gè)khungtaskd內(nèi)核線程對(duì)TASK_UNINTERRUPTIBLE狀態(tài)進(jìn)行檢測(cè),不能讓他失控了。khungtaskd會(huì)定期的喚醒,如果超過(guò)120s都還沒(méi)有調(diào)度,內(nèi)核就會(huì)通過(guò)打印警告和堆棧信息。當(dāng)然,不一定就是120s,可以通過(guò)下面選項(xiàng)進(jìn)行定制

sysctl?kernel.hung_task_timeout_secs

說(shuō)了這么多,我們?cè)趺粗赖降子袥](méi)有出現(xiàn)這個(gè)狀態(tài),哪里看?可以通過(guò)/proc和ps進(jìn)行查看

  • 睡眠進(jìn)程和等待隊(duì)列

不管是上面提到的可中斷的睡眠進(jìn)程還是不可中斷的睡眠進(jìn)程,都離不開一種數(shù)據(jù)結(jié)構(gòu)---隊(duì)列。哦?假設(shè)進(jìn)程A因?yàn)槟衬吃蛐枰菝?,為啥要休眠,等待的資源遲遲拿不到或者等待的事件總是不來(lái),沒(méi)法進(jìn)行下一步操作,這個(gè)時(shí)候內(nèi)核來(lái)了,"行吧,我不會(huì)拋棄你,我一定會(huì)想辦法讓你和等待的資源(事件)扯上關(guān)系",只要等待的時(shí)機(jī)到來(lái)我就喚醒你,這采用的方法即"等待隊(duì)列"。如果進(jìn)一步深究,想了解它的底層實(shí)現(xiàn)(采用了雙向鏈表),文末我會(huì)給大家推薦基本書籍。

  • TASK_STOPPED狀態(tài)于TASK_TRACED狀態(tài)

TASK_STOPPED狀態(tài)屬于比較特殊的狀態(tài),可以通過(guò)SIGCONT信號(hào)回復(fù)進(jìn)程的執(zhí)行

TASK_STOPPED

TASK_TRACED是被跟蹤的狀態(tài),進(jìn)程會(huì)停下來(lái)等待跟蹤它的進(jìn)程對(duì)它進(jìn)行進(jìn)一步的操作

  • EXIT_ZOMBIE狀態(tài)與EXIT_DEAD狀態(tài)

當(dāng)進(jìn)程儲(chǔ)于這兩種的任意一種,就可以宣布"死亡" 。

三狀態(tài)

就緒 —> 執(zhí)行:準(zhǔn)備就緒,調(diào)度器滿足了的需求,給我一種策略,我就可從就緒變?yōu)閳?zhí)行的狀態(tài);

執(zhí)行 —> 阻塞:不是每個(gè)進(jìn)程都是那么一帆風(fēng)順,就像我們每次考試,不管是中考,高考還是考研,難免都會(huì)出現(xiàn)磕磕盼盼,遇到了可能暫時(shí)會(huì)阻擋我們前行的小事兒,可是要相信不會(huì)一直的阻擋我們,只要我們有恒心堅(jiān)持,時(shí)機(jī)到來(lái),你也準(zhǔn)備好了,那就美哉。回到這里,對(duì)于進(jìn)程而言,當(dāng)需要等到某個(gè)事情發(fā)生而無(wú)法執(zhí)行的時(shí)候,進(jìn)程就變?yōu)?strong style="font-size: inherit;line-height: inherit;color: rgb(255, 69, 0);">阻塞的狀態(tài)。比如當(dāng)前進(jìn)程提出輸入請(qǐng)求,如進(jìn)程提出輸入/輸出請(qǐng)求,進(jìn)程所申請(qǐng)資源(主存空間或外部設(shè)備)得不到滿足時(shí)變成等待資源狀態(tài),進(jìn)程運(yùn)行中出現(xiàn)了故障(程序出錯(cuò)或主存儲(chǔ)器讀寫錯(cuò)等)變成等待干預(yù)狀態(tài)等等;

阻塞 —> 就緒:處于阻塞狀態(tài)的進(jìn)程,在其等待的事件已經(jīng)發(fā)生,如輸入/輸出完成,資源得到滿足或錯(cuò)誤處理完畢時(shí),處于等待狀態(tài)的進(jìn)程并不馬上轉(zhuǎn)入執(zhí)行狀態(tài),而是先轉(zhuǎn)入就緒狀態(tài),然后再由系統(tǒng)進(jìn)程調(diào)度程序在適當(dāng)?shù)臅r(shí)候?qū)⒃撨M(jìn)程轉(zhuǎn)為執(zhí)行狀態(tài);

執(zhí)行 —> 就緒:正在執(zhí)行的進(jìn)程,因時(shí)間片用完而被暫停執(zhí)行,或在采用搶先式優(yōu)先級(jí)調(diào)度算法的系統(tǒng)中,當(dāng)有更高優(yōu)先級(jí)的進(jìn)程要運(yùn)行而被迫讓出處理機(jī)時(shí),該進(jìn)程便由執(zhí)行狀態(tài)轉(zhuǎn)變?yōu)榫途w狀態(tài)。

6、進(jìn)程間的通信方式有哪些?

管道

學(xué)習(xí)軟件工程規(guī)范的時(shí)候,我們知道瀑布模型,在整個(gè)項(xiàng)目開發(fā)過(guò)程分為多個(gè)階段,上一階段的輸出作為下一階段的輸入。各個(gè)階段的具體內(nèi)容如下圖所示

最初我們?cè)趯W(xué)習(xí)Linux基本命令使用的時(shí)候,我們經(jīng)常通過(guò)多個(gè)命令的組合來(lái)完成我們的需求。比如說(shuō)我們想知道如何查看進(jìn)程或者端口是否在使用,會(huì)使用下面的這條命令

netstat -nlp | grep XXX

這里的"|"實(shí)際上就是管道的意思。"|"前面部分作為"|"后面的輸入,很明顯是單向的傳輸,這樣的管道我們叫做"匿名管道",自行創(chuàng)建和銷毀。既然有匿名管道,應(yīng)該就有帶名字的管道"命名管道"。如果你想雙向傳輸,可以考慮使用兩個(gè)管道拼接即可。

創(chuàng)建命名管道的方式

mkfifo test

test即為管道的名稱,在Linux中一切皆文件,管道也是以文件的方式存在,咋們可以使用ls -l 查看下文件的屬性,它會(huì)"p"標(biāo)識(shí)。

下面我們向管道寫入內(nèi)容

echo "666" > test

此時(shí)按道理來(lái)說(shuō)咋們已經(jīng)將內(nèi)容寫入了test,沒(méi)有直接輸出是因?yàn)槲覀冃枰_啟另一個(gè)終端進(jìn)行輸出(可以理解為暫存管道)

cat < test

ok,我們發(fā)現(xiàn)管道內(nèi)容被讀出來(lái),同時(shí)echo退出。那么管道這種通信方式有什么缺點(diǎn)?我們知道瀑布模型的軟件開發(fā)模式是非常低下的,同理采用管道進(jìn)行通信的效率也很低,因?yàn)榧僭O(shè)現(xiàn)在有AB兩個(gè)進(jìn)程,A進(jìn)程將數(shù)據(jù)寫入管道,B進(jìn)程需要等待A進(jìn)程將信息寫完以后才能讀出來(lái),所以這種方案不適合頻繁的通信。那優(yōu)點(diǎn)是什么?

最明顯的優(yōu)點(diǎn)就是簡(jiǎn)單,我們平時(shí)經(jīng)常使用以致于都不知道這是管道。鑒于上面的缺點(diǎn),我們?cè)趺慈浹a(bǔ)呢?接著往下看

消息隊(duì)列

管道通信屬于一股腦的輸入,能不能稍微溫柔點(diǎn)有規(guī)矩點(diǎn)的發(fā)送消息?

答:可以的。消息隊(duì)列在發(fā)送數(shù)據(jù)的時(shí)候,按照一個(gè)個(gè)獨(dú)立單元(消息體)進(jìn)行發(fā)送,其中每個(gè)消息體規(guī)定大小塊,同時(shí)發(fā)送方和接收方約定好消息類型或者正文的格式。

在管道中,其大小受限且只能承載無(wú)格式字節(jié)流的方式,而消息隊(duì)列允許不同進(jìn)程以消息隊(duì)列的形式發(fā)送給任意的進(jìn)程。

但是當(dāng)發(fā)送到消息隊(duì)列的數(shù)據(jù)太大,需要拷貝的時(shí)間也就越多,所以還有其他的方式?繼續(xù)看

共享內(nèi)存

使用消息隊(duì)列可以達(dá)到不錯(cuò)的效果,但是如果我們兩個(gè)部門需要交換比較大的數(shù)據(jù)的時(shí)候,一發(fā)一收還是不能及時(shí)的感知數(shù)據(jù)。能不能更好的辦法,雙方能很快的分享內(nèi)容數(shù)據(jù),答:有的,共享內(nèi)存

我們知道每個(gè)進(jìn)程都有自己的虛擬內(nèi)存空間,不同的進(jìn)程映射到不同的物理內(nèi)存空間。那么我們可不可以申請(qǐng)一塊虛擬地址空間,不同進(jìn)程通過(guò)這塊虛擬地址空間映射到相同的屋里地址空間呢?這樣不同進(jìn)程就可以及時(shí)的感知進(jìn)程都干了啥,就不需要再拷貝來(lái)拷貝去。

我們可以通過(guò)shmget創(chuàng)建一份共享內(nèi)存,并可以通過(guò)ipcs命令查看我們創(chuàng)建的共享內(nèi)存。此時(shí)如果一個(gè)進(jìn)程需要訪問(wèn)這段內(nèi)存,需要將這個(gè)內(nèi)存加載到自己虛擬地址空間的一個(gè)位置,讓內(nèi)核給它一個(gè)合法地址。使用完畢接觸板頂并刪除內(nèi)存對(duì)象。

那么問(wèn)題來(lái)了,這么多進(jìn)程都共享這塊內(nèi)存,如果同時(shí)都往里面寫內(nèi)容,難免會(huì)出現(xiàn)沖突的現(xiàn)象,比如A進(jìn)程寫了數(shù)字5,B進(jìn)程同樣的地址寫了6就直接給覆蓋了,這樣就不友好了,怎么辦?繼續(xù)往下看

信號(hào)量

為了防止沖突,我們得有個(gè)約束或者說(shuō)一種保護(hù)機(jī)制。使得同一份共享的資源只能一個(gè)進(jìn)程使用,這里就出現(xiàn)了信號(hào)量機(jī)制。

信號(hào)量實(shí)際上是一個(gè)計(jì)數(shù)器,這里需要注意下,信號(hào)量主要實(shí)現(xiàn)進(jìn)程之間的同步和互斥,而不是存儲(chǔ)通信內(nèi)容。

信號(hào)量定義了兩種操作,p操作和v操作,p操作為申請(qǐng)資源,會(huì)將數(shù)值減去M,表示這部分被他使用了,其他進(jìn)程暫時(shí)不能用。v操作是歸還資源操作,告知?dú)w還了資源可以用這部分。

信號(hào)

從管道----消息隊(duì)列-共享內(nèi)存/信號(hào)量,有需要等待的管道機(jī)制,共享內(nèi)存空間的進(jìn)程通信方式,還有一種特殊的方式--信號(hào)

我們或許聽說(shuō)過(guò)運(yùn)維或者部分開發(fā)需要7 * 24小時(shí)值守(項(xiàng)目需要上線的時(shí)候),當(dāng)然也有各種監(jiān)管,告警系統(tǒng),一旦出現(xiàn)系統(tǒng)資源緊張等問(wèn)題就會(huì)告知開發(fā)或運(yùn)維人員,對(duì)應(yīng)到操作系統(tǒng)中,這就是信號(hào)

在操作系統(tǒng)中,不同信號(hào)用不同的值表示,每個(gè)信號(hào)設(shè)置相應(yīng)的函數(shù),一旦進(jìn)程發(fā)送某一個(gè)信號(hào)給另一個(gè)進(jìn)程,另一進(jìn)程將執(zhí)行相應(yīng)的函數(shù)進(jìn)行處理。也就是說(shuō)把可能出現(xiàn)的異常等問(wèn)題準(zhǔn)備好,一旦信號(hào)產(chǎn)生就執(zhí)行相應(yīng)的邏輯即可。

套接字

上面的幾種方式都是單機(jī)情況下多個(gè)進(jìn)程的通信方式,如果我想和相隔幾千里的小姐姐通信怎么辦?

這就需要套接字socket了。其實(shí)這玩意隨處可見(jiàn),我們平時(shí)的聊天,我們天天請(qǐng)求瀏覽器給予的響應(yīng)等,都是這老鐵。

小結(jié)

分享了一下幾種進(jìn)程間通信方式,希望大家能知其然并知其所以然,機(jī)械式的記憶容易忘記哦。

  • 管道

  • 消息隊(duì)列

  • 共享內(nèi)存

  • 信號(hào)量

  • 信號(hào)

  • 套接字

7、進(jìn)程的調(diào)度算法有哪些?

調(diào)度算法是指:調(diào)度程序是內(nèi)核的重要組成部分,決定這下一個(gè)要運(yùn)行的進(jìn)程。那么根據(jù)系統(tǒng)的資源分配策略所規(guī)定的資源分配算法。常用的調(diào)度算法有:先來(lái)先服務(wù)調(diào)度算法、時(shí)間片輪轉(zhuǎn)調(diào)度法、短作業(yè)優(yōu)先調(diào)度算法、最短剩余時(shí)間優(yōu)先、高響應(yīng)比優(yōu)先調(diào)度算法、優(yōu)先級(jí)調(diào)度算法等等。

  • 先來(lái)先服務(wù)調(diào)度算法

先來(lái)先服務(wù)讓我們想起了隊(duì)列的先進(jìn)先出特性,每一次的調(diào)度都從隊(duì)列中選擇最先進(jìn)入隊(duì)列的投入運(yùn)行。

先來(lái)先服務(wù)
  • 時(shí)間片輪轉(zhuǎn)調(diào)度算法

先來(lái)理解輪轉(zhuǎn),假設(shè)當(dāng)前進(jìn)程A、B、C、D,按照進(jìn)程到達(dá)的時(shí)間排序,而且每個(gè)進(jìn)行都有著同樣大小的時(shí)間片。如果這個(gè)進(jìn)程在當(dāng)前的時(shí)間片運(yùn)行結(jié)束,啥事兒沒(méi)有,直接將進(jìn)程從隊(duì)列移除完事兒。如果進(jìn)程在這個(gè)時(shí)間片跑完都沒(méi)有結(jié)束,進(jìn)程變?yōu)榈却隣顟B(tài),放在進(jìn)程尾部直到所有進(jìn)程執(zhí)行完畢。

為什么進(jìn)程要切換,切換無(wú)外乎是時(shí)間片夠用或者不夠用。如果時(shí)間片夠用,那么進(jìn)程可以運(yùn)行到結(jié)束,結(jié)束后刪除啟動(dòng)新的時(shí)間片。如果時(shí)間片不夠用,對(duì)不起,暫時(shí)只能完成一部分任務(wù)(變?yōu)榈却隣顟B(tài)),過(guò)后再等待 CPU ?的調(diào)度。網(wǎng)上開源的代碼太多,怎么實(shí)現(xiàn),大家可以參照加深影響。

  • 短作業(yè)優(yōu)先調(diào)度算法

短作業(yè)優(yōu)先調(diào)度算法,從名稱可以清晰的知道「短作業(yè)」意味著執(zhí)行時(shí)間比較短,「優(yōu)先」代表執(zhí)行順序。結(jié)合就是"短者吃香"。那么多短吃香?進(jìn)程不可能都短,也有需要執(zhí)行時(shí)間比較長(zhǎng)的進(jìn)程怎么辦?一直等待,直到餓死麥?而且有些進(jìn)程比較緊急,能夠得到先執(zhí)行?這些都是此算法所出現(xiàn)的問(wèn)題,然后出現(xiàn)下面的一些算法

  • 最短剩余時(shí)間優(yōu)先調(diào)度算法

最短剩余時(shí)間是針對(duì)最短進(jìn)程優(yōu)先增加了搶占機(jī)制的版本。在這種情況下,進(jìn)程調(diào)度總是選擇預(yù)期剩余時(shí)間最短的進(jìn)程。當(dāng)一個(gè)進(jìn)程加入到就緒隊(duì)列時(shí),他可能比當(dāng)前運(yùn)行的進(jìn)程具有更短的剩余時(shí)間,因此只要新進(jìn)程就緒,調(diào)度程序就能可能搶占當(dāng)前正在運(yùn)行的進(jìn)程。像最短進(jìn)程優(yōu)先一樣,調(diào)度程序正在執(zhí)行選擇函數(shù)是必須有關(guān)于處理時(shí)間的估計(jì),并且存在長(zhǎng)進(jìn)程饑餓的危險(xiǎn)。

  • 高響應(yīng)比優(yōu)先調(diào)度算法

什么是高響應(yīng)比,有響應(yīng)之前應(yīng)該會(huì)有請(qǐng)求,相當(dāng)于是請(qǐng)求+響應(yīng)+優(yōu)先,算是一種綜合的調(diào)度算法。也就是它結(jié)合了短作業(yè)優(yōu)先,先來(lái)先服務(wù)以及長(zhǎng)作業(yè)的一些特性。ok,那么這三種是如何體現(xiàn)出來(lái)的

首先來(lái)說(shuō)短作業(yè)優(yōu)先。等待時(shí)間我們假設(shè)相等,服務(wù)時(shí)間很短,這樣的話短作業(yè)就會(huì)有更高的優(yōu)先權(quán)。

再來(lái)看先來(lái)先服務(wù)。假設(shè)服務(wù)時(shí)間相同,先來(lái)的自然等待時(shí)間較長(zhǎng),優(yōu)先級(jí)越高。

上面說(shuō)長(zhǎng)作業(yè)很可能因?yàn)榈却龝r(shí)間過(guò)長(zhǎng),容易餓死。在這里不會(huì),仿佛像醫(yī)生的這個(gè)職業(yè),工作越久資歷越老,優(yōu)先級(jí)越來(lái)越高,越來(lái)越吃香

  • 優(yōu)先級(jí)調(diào)度算法

優(yōu)先級(jí)調(diào)度算法每次從后備作業(yè)隊(duì)列中選擇優(yōu)先級(jí)最髙的一個(gè)或幾個(gè)作業(yè),將它們調(diào)入內(nèi)存,分配必要的資源,創(chuàng)建進(jìn)程并放入就緒隊(duì)列。在進(jìn)程調(diào)度中,優(yōu)先級(jí)調(diào)度算法每次從就緒隊(duì)列中選擇優(yōu)先級(jí)最高的進(jìn)程,將處理機(jī)分配給它,使之投入運(yùn)行。

8、什么是死鎖?

死鎖,顧名思義就是導(dǎo)致線程卡死的鎖沖突,例如下面的這種情況

死鎖

線程 1 已經(jīng)成功拿到了互斥量 1 ,正在申請(qǐng)互斥量 2 ,而同時(shí)在另一個(gè) ?CPU ? 上,線程 2 已經(jīng)拿到了互
斥量 2 ,正在申請(qǐng)互斥量 1 。彼此占有對(duì)方正在申請(qǐng)的互斥量,結(jié)局就是誰(shuí)也沒(méi)辦法拿到想要的互斥
量,于是死鎖就發(fā)生了。

資源占用

稍微復(fù)雜一點(diǎn)的情況

在這里插入圖片描述

存在多個(gè)互斥量的情況下,避免死鎖最簡(jiǎn)單的方法就是總是按照一定的先后順序申請(qǐng)這些互斥
量。還是以剛才的例子為例,如果每個(gè)線程都按照先申請(qǐng)互斥量 1 ,再申請(qǐng)互斥量 2 的順序執(zhí)行,死鎖
就不會(huì)發(fā)生。有些互斥量有明顯的層級(jí)關(guān)系,但是也有一些互斥量原本就沒(méi)有特定的層級(jí)關(guān)系,不過(guò)
沒(méi)有關(guān)系,可以人為干預(yù),讓所有的線程必須遵循同樣的順序來(lái)申請(qǐng)互斥量

9、產(chǎn)生死鎖的原因?

由于系統(tǒng)中存在一些不可剝奪資源,而當(dāng)兩個(gè)或兩個(gè)以上進(jìn)程占有自身資源,并請(qǐng)求對(duì)方資源時(shí),會(huì)導(dǎo)致每個(gè)進(jìn)程都無(wú)法向前推進(jìn),這就是死鎖。

  • 競(jìng)爭(zhēng)資源

例如:系統(tǒng)中只有一臺(tái)打印機(jī),可供進(jìn)程 A 使用,假定 A 已占用了打印機(jī),若 B 繼續(xù)要求打印機(jī)打印將被阻塞。

系統(tǒng)中的資源可以分為兩類:

  1. 可剝奪資源:是指某進(jìn)程在獲得這類資源后,該資源可以再被其他進(jìn)程或系統(tǒng)剝奪, CPU ? 和主存均屬于可剝奪性資源;

  2. 不可剝奪資源,當(dāng)系統(tǒng)把這類資源分配給某進(jìn)程后,再不能強(qiáng)行收回,只能在進(jìn)程用完后自行釋放,如磁帶機(jī)、打印機(jī)等。

  • 進(jìn)程推進(jìn)順序不當(dāng)

例如:進(jìn)程 A 和 進(jìn)程 B 互相等待對(duì)方的數(shù)據(jù)。

10、死鎖產(chǎn)生的必要條件?

互斥

要求各個(gè)資源互斥,如果這些資源都是可以共享的,那么多個(gè)進(jìn)程直接共享即可,不會(huì)存在等待的尷尬場(chǎng)景

非搶占

要求進(jìn)程所占有的資源使用完后主動(dòng)釋放即可,其他的進(jìn)程休想搶占這些資源。原因很簡(jiǎn)單,如果可以搶占,直接拿就好了,不會(huì)進(jìn)入尷尬的等待場(chǎng)景

要求進(jìn)程是在占有(holding)至少一個(gè)資源的前提下,請(qǐng)求(waiting)新的資源的。由于新的資源被其它進(jìn)程占有,此時(shí),發(fā)出請(qǐng)求的進(jìn)程就會(huì)帶著自己占有的資源進(jìn)入阻塞狀態(tài)。假設(shè) P1,P2 分別都需要 R1,R2 資源,如果是下面這種方式:

P1:??????????P2:
request(R1)??request(R2)
request(R2)??request(R1)?
?

如果 P1 請(qǐng)求到了 R1 資源之后,P2 請(qǐng)求到了 R2 資源,那么此后不管是哪個(gè)進(jìn)程再次請(qǐng)求資源,都是在占有資源的前提下請(qǐng)求的,此時(shí)就會(huì)帶著這個(gè)資源陷入阻塞狀態(tài)。P1 和 P2 需要互相等待,發(fā)生了死鎖。

換一種情況:

P1:??????????P2:
request(R1)??request(R1)
request(R2)??request(R2)?
?

如果 P1 請(qǐng)求到了 R1 資源,那么 P2 在請(qǐng)求 R1 的時(shí)候雖然也會(huì)阻塞,但是是在不占有資源的情況下阻塞的,不像之前那樣占有 R2。所以,此時(shí) P1 可以正常完成任務(wù)并釋放 R1,P2 拿到 R1 之后再去執(zhí)行任務(wù)。這種情況就不會(huì)發(fā)生死鎖。

  • 循環(huán)等待

要求存在一條進(jìn)程資源的循環(huán)等待鏈,鏈中的每一個(gè)進(jìn)程占有的資源同時(shí)被另一個(gè)進(jìn)程所請(qǐng)求。

發(fā)生死鎖時(shí)一定有循環(huán)等待(因?yàn)槭撬梨i的必要條件),但是發(fā)生循環(huán)等待的時(shí)候不一定會(huì)發(fā)生死鎖。這是因?yàn)?,如果循環(huán)等待鏈中的 P1 和 鏈外的 P6 都占有某個(gè)進(jìn)程 P2 請(qǐng)求的資源,那么 P2 完全可以選擇不等待 P1 釋放該資源,而是等待 P6 釋放資源。這樣就不會(huì)發(fā)生死鎖了。

11、解決死鎖的基本方法?

如果我們已經(jīng)知道死鎖形成的必要條件,逐一攻破即可。

  • 破壞互斥

通過(guò)與鎖完全不同的同步方式CAS,CAS提供原子性支持,實(shí)現(xiàn)各種無(wú)鎖的數(shù)據(jù)結(jié)構(gòu),不僅可以避免互斥鎖帶來(lái)的開銷也可避免死鎖問(wèn)題。

  • 破壞不搶占

如果一個(gè)線程已經(jīng)獲取到了一些鎖,那么在這個(gè)線程釋放鎖之前這些鎖是不會(huì)被強(qiáng)制搶占的。但是為了防止死鎖的發(fā)生,我們可以選擇讓線程在獲取后續(xù)的鎖失敗時(shí)主動(dòng)放棄自己已經(jīng)持有的鎖并在之后重試整個(gè)任務(wù),這樣其他等待這些鎖的線程就可以繼續(xù)執(zhí)行了。這樣就完美了嗎?當(dāng)然不

這種方式雖然可以在一定程度上避免死鎖,但是如果多個(gè)相互存在競(jìng)爭(zhēng)的線程不斷的放棄重啟放棄循環(huán),就會(huì)出現(xiàn)活鎖的問(wèn)題,此時(shí)線程雖然沒(méi)有因?yàn)殒i沖突被卡死,但是仍然會(huì)因?yàn)樽枞麜r(shí)間太長(zhǎng)處于重試當(dāng)中。怎么辦?

方案1:給任務(wù)重試部分增加隨機(jī)延遲時(shí)間,降低任務(wù)沖突的概率

  • 破壞環(huán)路等待

在實(shí)踐的過(guò)程中,采用破壞環(huán)路等待的方式非常常見(jiàn),這種技術(shù)叫做"鎖排序"。很好理解,我們假設(shè)現(xiàn)在有個(gè)數(shù)組A,采用單向訪問(wèn)的方式(從前往后),依次訪問(wèn)并加鎖,這樣一來(lái),線程只會(huì)向前單向等待鎖釋放,自然也就無(wú)法形成一個(gè)環(huán)路了。

說(shuō)到這里,我想說(shuō)死鎖不僅僅出現(xiàn)在多線程編程領(lǐng)域,在數(shù)據(jù)庫(kù)的訪問(wèn)也是非常的常見(jiàn),比如我們需要更新數(shù)據(jù)庫(kù)的幾行數(shù)據(jù),就得先獲取這些數(shù)據(jù)的鎖,然后通過(guò)排序的方式阻止數(shù)據(jù)層發(fā)生死鎖。

這樣就完美了?當(dāng)然沒(méi)有,那會(huì)出現(xiàn)什么問(wèn)題?

這種方案也存在它的缺點(diǎn),比如在大型系統(tǒng)當(dāng)中,不同模塊直接解耦和隔離得非常徹底,不同模塊開發(fā)人員不清楚其細(xì)節(jié),在這樣的情況下就很難做到整個(gè)系統(tǒng)層面的全局鎖排序了。在這種情況下,我們可以對(duì)方案進(jìn)行擴(kuò)充,例如Linux在內(nèi)存映射代碼就使用了一種鎖分組排序的方式來(lái)解決這個(gè)問(wèn)題。鎖分組排序首先按模塊將鎖分為了不同的組,每個(gè)組之間定義了嚴(yán)格的加鎖順序,然后再在組內(nèi)對(duì)具體的鎖按規(guī)則進(jìn)行排序,這樣就保證了全局的加鎖順序一致。在Linux的對(duì)應(yīng)的源碼頂部,我們可以看到有非常詳盡的注釋定義了明確的鎖排序規(guī)則。

這種解決方案如果規(guī)模過(guò)大的話即使可以實(shí)現(xiàn)也會(huì)非常的脆弱,只要有一個(gè)加鎖操作沒(méi)有遵守鎖排序規(guī)則就有可能會(huì)引發(fā)死鎖。不過(guò)在像微服務(wù)之類解耦比較充分的場(chǎng)景下,只要架構(gòu)拆分合理,任務(wù)模塊盡可能小且不會(huì)將加鎖范圍擴(kuò)大到模塊之外,那么鎖排序?qū)⑹且环N非常實(shí)用和便捷的死鎖阻止技術(shù)

12、怎么預(yù)防死鎖?

破壞請(qǐng)求條件:一次性分配所有資源,這樣就不會(huì)再有請(qǐng)求了;

破壞請(qǐng)保持條件:只要有一個(gè)資源得不到分配,也不給這個(gè)進(jìn)程分配其他的資源:

破壞不可剝奪條件:當(dāng)某進(jìn)程獲得了部分資源,但得不到其它資源,則釋放已占有的資源;

破壞環(huán)路等待條件:系統(tǒng)給每類資源賦予一個(gè)編號(hào),每一個(gè)進(jìn)程按編號(hào)遞增的順序請(qǐng)求資源,釋放則相反。

13、怎么避免死鎖?

  • 銀行家算法

當(dāng)進(jìn)程首次申請(qǐng)資源時(shí),要測(cè)試該進(jìn)程對(duì)資源的最大需求量,如果系統(tǒng)現(xiàn)存的資源可以滿足它的最大需求量則按當(dāng)前的申請(qǐng)量分配資源,否則就推遲分配。

當(dāng)進(jìn)程在執(zhí)行中繼續(xù)申請(qǐng)資源時(shí),先測(cè)試該進(jìn)程已占用的資源數(shù)與本次申請(qǐng)資源數(shù)之和是否超過(guò)了該進(jìn)程對(duì)資源的最大需求量。若超過(guò)則拒絕分配資源。若沒(méi)超過(guò)則再測(cè)試系統(tǒng)現(xiàn)存的資源能否滿足該進(jìn)程尚需的最大資源量,若滿足則按當(dāng)前的申請(qǐng)量分配資源,否則也要推遲分配。

  • 安全序列

是指系統(tǒng)能按某種進(jìn)程推進(jìn)順序(P1, P2, P3, …, Pn),為每個(gè)進(jìn)程 Pi 分配其所需要的資源,直至滿足每個(gè)進(jìn)程對(duì)資源的最大需求,使每個(gè)進(jìn)程都可以順序地完成。這種推進(jìn)順序就叫安全序列【銀行家算法的核心就是找到一個(gè)安全序列】。

  • 系統(tǒng)安全狀態(tài)

如果系統(tǒng)能找到一個(gè)安全序列,就稱系統(tǒng)處于安全狀態(tài),否則,就稱系統(tǒng)處于不安全狀態(tài)。

14、怎么解除死鎖?

  • 資源剝奪:掛起某些死鎖進(jìn)程,并搶占它的資源,將這些資源分配給其他死鎖進(jìn)程(但應(yīng)該防止被掛起的進(jìn)程長(zhǎng)時(shí)間得不到資源);

  • 撤銷進(jìn)程:強(qiáng)制撤銷部分、甚至全部死鎖進(jìn)程并剝奪這些進(jìn)程的資源(撤銷的原則可以按進(jìn)程優(yōu)先級(jí)和撤銷進(jìn)程代價(jià)的高低進(jìn)行);

  • 進(jìn)程回退:讓一個(gè)或多個(gè)進(jìn)程回退到足以避免死鎖的地步。進(jìn)程回退時(shí)自愿釋放資源而不是被剝奪。要求系統(tǒng)保持進(jìn)程的歷史信息,設(shè)置還原點(diǎn)。

15、什么是緩沖區(qū)溢出?有什么危害?

官話

緩沖區(qū)溢出是指當(dāng)計(jì)算機(jī)向緩沖區(qū)內(nèi)填充數(shù)據(jù)時(shí)超過(guò)了緩沖區(qū)本身的容量,溢出的數(shù)據(jù)覆蓋在合法數(shù)據(jù)上

舉個(gè)例子

一個(gè)兩升的杯子,你如果想導(dǎo)入三升,怎么做?其他一生只好流出去,不是打濕了電腦就是那啥。

16、物理地址、邏輯地址、線性地址

  • 物理地址:它是地址轉(zhuǎn)換的最終地址,是內(nèi)存單元真正的地址。如果采用了分頁(yè)機(jī)制,那么線性地址會(huì)通過(guò)頁(yè)目錄和頁(yè)表得方式轉(zhuǎn)換為物理地址。如果沒(méi)有啟用則線性地址即為物理地址

  • 邏輯地址:在編寫c語(yǔ)言的時(shí)候,通過(guò)&操作符可以讀取指針變量本省得值,這個(gè)值就是邏輯地址。實(shí)際上是當(dāng)前進(jìn)程得數(shù)據(jù)段得地址,和真實(shí)的物理地址沒(méi)有關(guān)系。只有當(dāng)在Intel實(shí)模式下,邏輯地址==物理地址。我們平時(shí)的應(yīng)用程序都是通過(guò)和邏輯地址打交道,至于分頁(yè),分段機(jī)制對(duì)他們而言是透明得。邏輯地址也稱作虛擬地址

  • 線性地址:線性地址是邏輯地址到物理地址的中間層。我們編寫的代碼會(huì)存在一個(gè)邏輯地址或者是段中得偏移地址,通過(guò)相應(yīng)的計(jì)算(加上基地址)生成線性地址。此時(shí)如果采用了分頁(yè)機(jī)制,那么吸納行地址再經(jīng)過(guò)變換即產(chǎn)生物理地址。在Intelk 80386中地址空間容量為4G,各個(gè)進(jìn)程地址空間隔離,意味著每個(gè)進(jìn)程獨(dú)享4G線性空間。多個(gè)進(jìn)程難免出現(xiàn)進(jìn)程之間的切換,線性空間隨之切換?;诜猪?yè)機(jī)制,對(duì)于4GB的線性地址一部分會(huì)被映射到物理內(nèi)存,一部分映射到磁盤作為交換文件,一部分沒(méi)有映射,通過(guò)下面加深一下印象

17、分頁(yè)與分段的區(qū)別?

我們知道計(jì)算機(jī)的五大組成部分分別為運(yùn)算器,存儲(chǔ)器,存儲(chǔ)器 ,輸入和輸出設(shè)備。我們的數(shù)據(jù)或者指定都需要存放內(nèi)存然后給 CPU ?大哥拿去執(zhí)行。我們平時(shí)寫的代碼不是直接操作的物理地址,我們所看到的地址實(shí)際上叫做虛擬地址,通過(guò)相應(yīng)的轉(zhuǎn)換規(guī)則將虛擬地址轉(zhuǎn)換為物理地址。

那么虛擬地址是怎么轉(zhuǎn)換為物理地址的呢?

第一種方式,采用一個(gè)映射表代表虛擬地址到物理地址的映射,在計(jì)算機(jī)中我們叫做頁(yè)表。頁(yè)表將內(nèi)存地址分為頁(yè)號(hào)偏移量,舉個(gè)例子

我們將高位部分稱為內(nèi)存地址的頁(yè)號(hào),后面的低位叫做內(nèi)存地址的偏移量。我們只需要保存虛擬地址內(nèi)存的頁(yè)號(hào)和物理內(nèi)存頁(yè)號(hào)之間的映射關(guān)系即可。

在這里插入圖片描述

這樣說(shuō)了,也就是三部曲

  • 虛擬地址-----> 頁(yè)號(hào)+偏移量

  • 通過(guò)頁(yè)表查詢出虛擬頁(yè)號(hào),對(duì)應(yīng)的物理頁(yè)號(hào)

  • 物理頁(yè)號(hào)+偏移量-----> 物理內(nèi)存地址

在這里插入圖片描述

這樣的方法,在32位的內(nèi)存地址,頁(yè)表需要多大的空間?

在一個(gè)32位的內(nèi)存地址空間,頁(yè)表需要記錄2^20個(gè)物理頁(yè)面的映射關(guān)系,可以想象為要給數(shù)組。那么一個(gè)頁(yè)號(hào)是完整的4字節(jié)。這樣一個(gè)頁(yè)表就是4MB。

再來(lái),我們知道進(jìn)程有各自的虛擬內(nèi)存空間,也就是說(shuō)每個(gè)進(jìn)程都需要一個(gè)這樣的頁(yè)表,不管此進(jìn)程是只有幾KB的程序還是需要GB的內(nèi)存空間都需要這樣的頁(yè)表,用這樣的結(jié)構(gòu)保存頁(yè)面,內(nèi)存的占用將非常的大,那其他方式是怎么樣的呢

多級(jí)頁(yè)表

同樣的虛擬內(nèi)存地址,偏移量部分和上面方式一樣,但是我們將頁(yè)號(hào)部分拆分為四段,從高到低分成4級(jí)到1級(jí)的4個(gè)頁(yè)表索引

二級(jí)索引

這樣一來(lái),每個(gè)進(jìn)程將有4級(jí)頁(yè)表。通過(guò)4級(jí)頁(yè)表的索引找到對(duì)應(yīng)的條目。通過(guò)這個(gè)條目找到3級(jí)頁(yè)表所在位置,4級(jí)的每一個(gè)條目可能有多個(gè)3級(jí)的條目,找到了3級(jí)的條目后找到對(duì)應(yīng)3級(jí)索引的條目,就這樣到達(dá)1級(jí)頁(yè)表。1級(jí)對(duì)應(yīng)的則為物理頁(yè)號(hào)。最終通過(guò)物理頁(yè)號(hào)+偏移量的方式獲取物理內(nèi)存地址。

18 為什么使用多級(jí)頁(yè)表

  • 使用多級(jí)頁(yè)表可以讓頁(yè)表在內(nèi)存中離散存儲(chǔ)。多級(jí)頁(yè)表通過(guò)索引就可以定位到具體的項(xiàng)。舉個(gè)例子,假設(shè)當(dāng)前虛擬地址空間為4G,每個(gè)頁(yè)的大小為4k,如果是一級(jí)頁(yè)表的話,共有2……20個(gè)頁(yè)表項(xiàng),假設(shè)每個(gè)頁(yè)表項(xiàng)需要4B,那么存放所有的頁(yè)表項(xiàng)需要4M,那么為了隨機(jī)訪問(wèn),我們就需要連續(xù)的4M內(nèi)存空間存放所有的頁(yè)表項(xiàng)。這樣一來(lái),隨著虛擬地址空間的增大,需要存放頁(yè)表所需的連續(xù)空間也就越來(lái)多大。如果使用多級(jí)頁(yè)表,我們只需要一頁(yè)存放目錄項(xiàng),頁(yè)表存放在內(nèi)存其他位置即可,下面有例子進(jìn)一步講解

  • 使用多級(jí)頁(yè)表更加節(jié)省頁(yè)表內(nèi)存。理論上,使用一級(jí)頁(yè)表,需要連續(xù)存儲(chǔ)空間存放所有項(xiàng)。使用多級(jí)頁(yè)表只需要給實(shí)際使用的的那些虛擬地址內(nèi)存的請(qǐng)求分配內(nèi)存

舉個(gè)例子

假設(shè)虛擬地址空間為4G,A進(jìn)程只是用 4M 的內(nèi)存空間。對(duì)于一級(jí)頁(yè)表,我們需要 4M 空間存放這4GB 虛擬地址對(duì)應(yīng)的頁(yè)表,然后找到進(jìn)程真正的 4M 內(nèi)存空間。這樣的話,A進(jìn)程本來(lái)只使用 4MB 內(nèi)存空間,但是為了訪問(wèn)它,我們需要為所有的虛擬地址空間建立頁(yè)表,豈不是很浪費(fèi)。對(duì)于二級(jí)頁(yè)表而言,使用一個(gè)頁(yè)目錄就可定位 4M 的內(nèi)存,存放一個(gè)頁(yè)目錄項(xiàng)需要 4k,還需要一頁(yè)存放進(jìn)程使用的 4M,4M=1024*4k,也就相當(dāng)于 1024 個(gè)頁(yè)表項(xiàng)就可以映射4M的內(nèi)存空間,那么總共就只需要4k(頁(yè)表)+4k(頁(yè)目錄)=8k來(lái)存放進(jìn)程需要的 4M 內(nèi)存空間對(duì)應(yīng)頁(yè)表和頁(yè)目錄項(xiàng)。這樣看來(lái)確實(shí)剩下不少的內(nèi)存。

那使用多級(jí)頁(yè)表有啥缺點(diǎn)?

還是有的,咋們使用一級(jí)頁(yè)表的時(shí)候,只需要訪問(wèn)兩次內(nèi)存,一次是訪問(wèn)頁(yè)表項(xiàng),一次是訪問(wèn)需要讀取的一頁(yè)數(shù)據(jù)。如果是二級(jí)頁(yè)表,就需要訪問(wèn)三次,第一次訪問(wèn)頁(yè)目錄,第二次訪問(wèn)頁(yè)表項(xiàng),第三次訪問(wèn)讀取的數(shù)據(jù)。訪問(wèn)次數(shù)的增加以為訪問(wèn)數(shù)據(jù)所花費(fèi)的總時(shí)間也增加

19、頁(yè)面置換算法有哪些?

請(qǐng)求調(diào)頁(yè),也稱按需調(diào)頁(yè),即對(duì)不在內(nèi)存中的“頁(yè)”,當(dāng)進(jìn)程執(zhí)行時(shí)要用時(shí)才調(diào)入,否則有可能到程序結(jié)束時(shí)也不會(huì)調(diào)入。而內(nèi)存中給頁(yè)面留的位置是有限的,在內(nèi)存中以為單位放置頁(yè)面。為了防止請(qǐng)求調(diào)頁(yè)的過(guò)程出現(xiàn)過(guò)多的內(nèi)存頁(yè)面錯(cuò)誤(即需要的頁(yè)面當(dāng)前不在內(nèi)存中,需要從硬盤中讀數(shù)據(jù),也即需要做頁(yè)面的替換)而使得程序執(zhí)行效率下降,我們需要設(shè)計(jì)一些頁(yè)面置換算法,頁(yè)面按照這些算法進(jìn)行相互替換時(shí),可以盡量達(dá)到較低的錯(cuò)誤率。常用的頁(yè)面置換算法如下:

  • 先進(jìn)先出置換算法(FIFO)

先進(jìn)先出,即淘汰最早調(diào)入的頁(yè)面。

  • 最佳置換算法(OPT)

選未來(lái)最遠(yuǎn)將使用的頁(yè)淘汰,是一種最優(yōu)的方案,可以證明缺頁(yè)數(shù)最小。

  • 最近最久未使用(LRU)算法

即選擇最近最久未使用的頁(yè)面予以淘汰

  • 時(shí)鐘(Clock)置換算法

時(shí)鐘置換算法也叫最近未用算法 NRU(Not RecentlyUsed)。該算法為每個(gè)頁(yè)面設(shè)置一位訪問(wèn)位,將內(nèi)存中的所有頁(yè)面都通過(guò)鏈接指針鏈成一個(gè)循環(huán)隊(duì)列。。

20 書籍/視頻學(xué)習(xí)推薦

書籍

  • Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)

  • 操作系統(tǒng)導(dǎo)論

  • 現(xiàn)代操作系統(tǒng)

  • 深入理解操作系統(tǒng)

視頻

  • B站 ----哈工大李志軍老師講解

https://www.bilibili.com/video/av17036347/

往期推薦







免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉