動(dòng)態(tài)分區(qū)分配算法有哪幾種?
本期是操作系統(tǒng)開(kāi)胃菜,既然是開(kāi)胃菜那字?jǐn)?shù)少一點(diǎn)好了哈哈,就先來(lái)21 道題,16213 個(gè)字好了。
還有本來(lái)想等到《逆襲進(jìn)大廠》系列出完之后再放出 PDF 的,可很多人讓我先出個(gè)第一版先看著…..
一開(kāi)始我是拒絕的,可真的太多人跟我說(shuō)了,考慮到最近金三銀四以及春招找工作期間很多人都需要這份資料,emm…
沒(méi)辦法,先出第一期好了。
以下是本期目錄,看看你會(huì)多少。
閑話少敘,開(kāi)車開(kāi)車!
1、進(jìn)程、線程和協(xié)程的區(qū)別和聯(lián)系
1、進(jìn)程是資源調(diào)度的基本單位,運(yùn)行一個(gè)可執(zhí)行程序會(huì)創(chuàng)建一個(gè)或多個(gè)進(jìn)程,進(jìn)程就是運(yùn)行起來(lái)的可執(zhí)行程序
2、線程是程序執(zhí)行的基本單位,是輕量級(jí)的進(jìn)程。每個(gè)進(jìn)程中都有唯一的主線程,且只能有一個(gè),主線程和進(jìn)程是相互依存的關(guān)系,主線程結(jié)束進(jìn)程也會(huì)結(jié)束。多提一句:協(xié)程是用戶態(tài)的輕量級(jí)線程,線程內(nèi)部調(diào)度的基本單位
2、線程與進(jìn)程的比較
1、線程啟動(dòng)速度快,輕量級(jí)
2、線程的系統(tǒng)開(kāi)銷小
3、線程使用有一定難度,需要處理數(shù)據(jù)一致性問(wèn)題
4、同一線程共享的有堆、全局變量、靜態(tài)變量、指針,引用、文件等,而獨(dú)自占有棧
3、一個(gè)進(jìn)程可以創(chuàng)建多少線程,和什么有關(guān)?
理論上,一個(gè)進(jìn)程可用虛擬空間是2G,默認(rèn)情況下,線程的棧的大小是1MB,所以理論上最多只能創(chuàng)建2048個(gè)線程。如果要?jiǎng)?chuàng)建多于2048的話,必須修改編譯器的設(shè)置。
因此,一個(gè)進(jìn)程可以創(chuàng)建的線程數(shù)由可用虛擬空間和線程的棧的大小共同決定,只要虛擬空間足夠,那么新線程的建立就會(huì)成功。如果需要?jiǎng)?chuàng)建超過(guò)2K以上的線程,減小你線程棧的大小就可以實(shí)現(xiàn)了,雖然在一般情況下,你不需要那么多的線程。過(guò)多的線程將會(huì)導(dǎo)致大量的時(shí)間浪費(fèi)在線程切換上,給程序運(yùn)行效率帶來(lái)負(fù)面影響。
4、外中斷和異常有什么區(qū)別?
外中斷是指由 CPU 執(zhí)行指令以外的事件引起,如 I/O 完成中斷,表示設(shè)備輸入/輸出處理已經(jīng)完成,處理器能夠發(fā)送下一個(gè)輸入/輸出請(qǐng)求。此外還有時(shí)鐘中斷、控制臺(tái)中斷等。
而異常時(shí)由 CPU 執(zhí)行指令的內(nèi)部事件引起,如非法操作碼、地址越界、算術(shù)溢出等。
5、進(jìn)程線程模型你知道多少?
對(duì)于進(jìn)程和線程的理解和把握可以說(shuō)基本奠定了對(duì)系統(tǒng)的認(rèn)知和把控能力。其核心意義絕不僅僅是“線程是調(diào)度的基本單位,進(jìn)程是資源分配的基本單位”這么簡(jiǎn)單。
多線程
我們這里討論的是用戶態(tài)的多線程模型,同一個(gè)進(jìn)程內(nèi)部有多個(gè)線程,所有的線程共享同一個(gè)進(jìn)程的內(nèi)存空間,進(jìn)程中定義的全局變量會(huì)被所有的線程共享,比如有全局變量int i = 10,這一進(jìn)程中所有并發(fā)運(yùn)行的線程都可以讀取和修改這個(gè)i的值,而多個(gè)線程被CPU調(diào)度的順序又是不可控的,所以對(duì)臨界資源的訪問(wèn)尤其需要注意安全。
我們必須知道,做一次簡(jiǎn)單的i = i + 1在計(jì)算機(jī)中并不是原子操作,涉及內(nèi)存取數(shù),計(jì)算和寫入內(nèi)存幾個(gè)環(huán)節(jié),而線程的切換有可能發(fā)生在上述任何一個(gè)環(huán)節(jié)中間,所以不同的操作順序很有可能帶來(lái)意想不到的結(jié)果。
但是,雖然線程在安全性方面會(huì)引入許多新挑戰(zhàn),但是線程帶來(lái)的好處也是有目共睹的。首先,原先順序執(zhí)行的程序(暫時(shí)不考慮多進(jìn)程)可以被拆分成幾個(gè)獨(dú)立的邏輯流,這些邏輯流可以獨(dú)立完成一些任務(wù)(最好這些任務(wù)是不相關(guān)的)。
比如 QQ 可以一個(gè)線程處理聊天一個(gè)線程處理上傳文件,兩個(gè)線程互不干涉,在用戶看來(lái)是同步在執(zhí)行兩個(gè)任務(wù),試想如果線性完成這個(gè)任務(wù)的話,在數(shù)據(jù)傳輸完成之前用戶聊天被一直阻塞會(huì)是多么尷尬的情況。
對(duì)于線程,我認(rèn)為弄清以下兩點(diǎn)非常重要:
線程之間有無(wú)先后訪問(wèn)順序(線程依賴關(guān)系)
多個(gè)線程共享訪問(wèn)同一變量(同步互斥問(wèn)題)
另外,我們通常只會(huì)去說(shuō)同一進(jìn)程的多個(gè)線程共享進(jìn)程的資源,但是每個(gè)線程特有的部分卻很少提及,除了標(biāo)識(shí)線程的tid,每個(gè)線程還有自己獨(dú)立的棧空間,線程彼此之間是無(wú)法訪問(wèn)其他線程棧上內(nèi)容的。
而作為處理機(jī)調(diào)度的最小單位,線程調(diào)度只需要保存線程棧、寄存器數(shù)據(jù)和PC即可,相比進(jìn)程切換開(kāi)銷要小很多。
線程相關(guān)接口不少,主要需要了解各個(gè)參數(shù)意義和返回值意義。
線程創(chuàng)建和結(jié)束
背景知識(shí):
在一個(gè)文件內(nèi)的多個(gè)函數(shù)通常都是按照main函數(shù)中出現(xiàn)的順序來(lái)執(zhí)行,但是在分時(shí)系統(tǒng)下,我們可以讓每個(gè)函數(shù)都作為一個(gè)邏輯流并發(fā)執(zhí)行,最簡(jiǎn)單的方式就是采用多線程策略。在main函數(shù)中調(diào)用多線程接口創(chuàng)建線程,每個(gè)線程對(duì)應(yīng)特定的函數(shù)(操作),這樣就可以不按照main函數(shù)中各個(gè)函數(shù)出現(xiàn)的順序來(lái)執(zhí)行,避免了忙等的情況。線程基本操作的接口如下。
相關(guān)接口:
創(chuàng)建線程:int pthread_create(pthread_t *pthread, const pthread_attr_t *attr, void (start_routine)(void *), void *agr);
創(chuàng)建一個(gè)新線程,pthread和start_routine不可或缺,分別用于標(biāo)識(shí)線程和執(zhí)行體入口,其他可以填NULL。
pthread:用來(lái)返回線程的tid,*pthread值即為tid,類型pthread_t == unsigned long int。
attr:指向線程屬性結(jié)構(gòu)體的指針,用于改變所創(chuàng)線程的屬性,填NULL使用默認(rèn)值。
start_routine:線程執(zhí)行函數(shù)的首地址,傳入函數(shù)指針。
arg:通過(guò)地址傳遞來(lái)傳遞函數(shù)參數(shù),這里是無(wú)符號(hào)類型指針,可以傳任意類型變量的地址,在被傳入函數(shù)中先強(qiáng)制類型轉(zhuǎn)換成所需類型即可。
獲得線程ID:pthread_t pthread_self();
調(diào)用時(shí),會(huì)打印線程ID。
等待線程結(jié)束:int pthread_join(pthread_t tid, void** retval);
主線程調(diào)用,等待子線程退出并回收其資源,類似于進(jìn)程中wait/waitpid回收僵尸進(jìn)程,調(diào)用pthread_join的線程會(huì)被阻塞。
tid:創(chuàng)建線程時(shí)通過(guò)指針得到tid值。
retval:指向返回值的指針。
結(jié)束線程:pthread_exit(void *retval);
子線程執(zhí)行,用來(lái)結(jié)束當(dāng)前線程并通過(guò)retval傳遞返回值,該返回值可通過(guò)pthread_join獲得。
retval:同上。
分離線程:int pthread_detach(pthread_t tid);
主線程、子線程均可調(diào)用。主線程中pthread_detach(tid),子線程中pthread_detach(pthread_self()),調(diào)用后和主線程分離,子線程結(jié)束時(shí)自己立即回收資源。
tid:同上。
線程屬性值修改
背景知識(shí):
線程屬性對(duì)象類型為pthread_attr_t,結(jié)構(gòu)體定義如下:
typedef struct{
int etachstate; // 線程分離的狀態(tài)
int schedpolicy; // 線程調(diào)度策略
struct sched_param schedparam; // 線程的調(diào)度參數(shù)
int inheritsched; // 線程的繼承性
int scope; // 線程的作用域
// 以下為線程棧的設(shè)置
size_t guardsize; // 線程棧末尾警戒緩沖大小
int stackaddr_set; // 線程的棧設(shè)置
void * stackaddr; // 線程棧的位置
size_t stacksize; // 線程棧大小
}pthread_arrt_t;
相關(guān)接口:
對(duì)上述結(jié)構(gòu)體中各參數(shù)大多有:pthread_attr_get()和pthread_attr_set()系統(tǒng)調(diào)用函數(shù)來(lái)設(shè)置和獲取。這里不一一羅列。
多進(jìn)程
每一個(gè)進(jìn)程是資源分配的基本單位。
進(jìn)程結(jié)構(gòu)由以下幾個(gè)部分組成:代碼段、堆棧段、數(shù)據(jù)段。代碼段是靜態(tài)的二進(jìn)制代碼,多個(gè)程序可以共享。
實(shí)際上在父進(jìn)程創(chuàng)建子進(jìn)程之后,父、子進(jìn)程除了pid外,幾乎所有的部分幾乎一樣。
父、子進(jìn)程共享全部數(shù)據(jù),但并不是說(shuō)他們就是對(duì)同一塊數(shù)據(jù)進(jìn)行操作,子進(jìn)程在讀寫數(shù)據(jù)時(shí)會(huì)通過(guò)寫時(shí)復(fù)制機(jī)制將公共的數(shù)據(jù)重新拷貝一份,之后在拷貝出的數(shù)據(jù)上進(jìn)行操作。
如果子進(jìn)程想要運(yùn)行自己的代碼段,還可以通過(guò)調(diào)用execv()函數(shù)重新加載新的代碼段,之后就和父進(jìn)程獨(dú)立開(kāi)了。
我們?cè)趕hell中執(zhí)行程序就是通過(guò)shell進(jìn)程先f(wàn)ork()一個(gè)子進(jìn)程再通過(guò)execv()重新加載新的代碼段的過(guò)程。
進(jìn)程創(chuàng)建與結(jié)束
背景知識(shí):
進(jìn)程有兩種創(chuàng)建方式,一種是操作系統(tǒng)創(chuàng)建的一種是父進(jìn)程創(chuàng)建的。從計(jì)算機(jī)啟動(dòng)到終端執(zhí)行程序的過(guò)程為:0號(hào)進(jìn)程 -> 1號(hào)內(nèi)核進(jìn)程 -> 1號(hào)用戶進(jìn)程(init進(jìn)程) -> getty進(jìn)程 -> shell進(jìn)程 -> 命令行執(zhí)行進(jìn)程。所以我們?cè)诿钚兄型ㄟ^(guò) ./program執(zhí)行可執(zhí)行文件時(shí),所有創(chuàng)建的進(jìn)程都是shell進(jìn)程的子進(jìn)程,這也就是為什么shell一關(guān)閉,在shell中執(zhí)行的進(jìn)程都自動(dòng)被關(guān)閉的原因。從shell進(jìn)程到創(chuàng)建其他子進(jìn)程需要通過(guò)以下接口。
相關(guān)接口:
創(chuàng)建進(jìn)程:pid_t fork(void);
返回值:出錯(cuò)返回-1;父進(jìn)程中返回pid > 0;子進(jìn)程中pid == 0
結(jié)束進(jìn)程:void exit(int status);
status是退出狀態(tài),保存在全局變量中S?,通常0表示正常退出。
獲得PID:pid_t getpid(void);
返回調(diào)用者pid。
獲得父進(jìn)程PID:pid_t getppid(void);
返回父進(jìn)程pid。
其他補(bǔ)充:
正常退出方式:exit()、_exit()、return(在main中)。
exit()和_exit()區(qū)別:exit()是對(duì)__exit()的封裝,都會(huì)終止進(jìn)程并做相關(guān)收尾工作,最主要的區(qū)別是_exit()函數(shù)關(guān)閉全部描述符和清理函數(shù)后不會(huì)刷新流,但是exit()會(huì)在調(diào)用_exit()函數(shù)前刷新數(shù)據(jù)流。
return和exit()區(qū)別:exit()是函數(shù),但有參數(shù),執(zhí)行完之后控制權(quán)交給系統(tǒng)。return若是在調(diào)用函數(shù)中,執(zhí)行完之后控制權(quán)交給調(diào)用進(jìn)程,若是在main函數(shù)中,控制權(quán)交給系統(tǒng)。
異常退出方式:abort()、終止信號(hào)。
Linux進(jìn)程控制
進(jìn)程地址空間(地址空間)
虛擬存儲(chǔ)器為每個(gè)進(jìn)程提供了獨(dú)占系統(tǒng)地址空間的假象。
盡管每個(gè)進(jìn)程地址空間內(nèi)容不盡相同,但是他們的都有相似的結(jié)構(gòu)。X86 Linux進(jìn)程的地址空間底部是保留給用戶程序的,包括文本、數(shù)據(jù)、堆、棧等,其中文本區(qū)和數(shù)據(jù)區(qū)是通過(guò)存儲(chǔ)器映射方式將磁盤中可執(zhí)行文件的相應(yīng)段映射至虛擬存儲(chǔ)器地址空間中。
有一些"敏感"的地址需要注意下,對(duì)于32位進(jìn)程來(lái)說(shuō),代碼段從0x08048000開(kāi)始。從0xC0000000開(kāi)始到0xFFFFFFFF是內(nèi)核地址空間,通常情況下代碼運(yùn)行在用戶態(tài)(使用0x00000000 ~ 0xC00000000的用戶地址空間),當(dāng)發(fā)生系統(tǒng)調(diào)用、進(jìn)程切換等操作時(shí)CPU控制寄存器設(shè)置模式位,進(jìn)入內(nèi)和模式,在該狀態(tài)(超級(jí)用戶模式)下進(jìn)程可以訪問(wèn)全部存儲(chǔ)器位置和執(zhí)行全部指令。
也就說(shuō)32位進(jìn)程的地址空間都是4G,但用戶態(tài)下只能訪問(wèn)低3G的地址空間,若要訪問(wèn)3G ~ 4G的地址空間則只有進(jìn)入內(nèi)核態(tài)才行。
進(jìn)程控制塊(處理機(jī))
進(jìn)程的調(diào)度實(shí)際就是內(nèi)核選擇相應(yīng)的進(jìn)程控制塊,被選擇的進(jìn)程控制塊中包含了一個(gè)進(jìn)程基本的信息。
上下文切換
內(nèi)核管理所有進(jìn)程控制塊,而進(jìn)程控制塊記錄了進(jìn)程全部狀態(tài)信息。每一次進(jìn)程調(diào)度就是一次上下文切換,所謂的上下文本質(zhì)上就是當(dāng)前運(yùn)行狀態(tài),主要包括通用寄存器、浮點(diǎn)寄存器、狀態(tài)寄存器、程序計(jì)數(shù)器、用戶棧和內(nèi)核數(shù)據(jù)結(jié)構(gòu)(頁(yè)表、進(jìn)程表、文件表)等。
進(jìn)程執(zhí)行時(shí)刻,內(nèi)核可以決定搶占當(dāng)前進(jìn)程并開(kāi)始新的進(jìn)程,這個(gè)過(guò)程由內(nèi)核調(diào)度器完成,當(dāng)調(diào)度器選擇了某個(gè)進(jìn)程時(shí)稱為該進(jìn)程被調(diào)度,該過(guò)程通過(guò)上下文切換來(lái)改變當(dāng)前狀態(tài)。
一次完整的上下文切換通常是進(jìn)程原先運(yùn)行于用戶態(tài),之后因系統(tǒng)調(diào)用或時(shí)間片到切換到內(nèi)核態(tài)執(zhí)行內(nèi)核指令,完成上下文切換后回到用戶態(tài),此時(shí)已經(jīng)切換到進(jìn)程B。
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場(chǎng)仿真助跑新能源汽車
-
11月20日火熱報(bào)名中>> 2024 智能家居出海論壇
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國(guó)智造CIO在線峰會(huì)
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
推薦專題
- 1 【一周車話】沒(méi)有方向盤和踏板的車,你敢坐嗎?
- 2 特斯拉發(fā)布無(wú)人駕駛車,還未迎來(lái)“Chatgpt時(shí)刻”
- 3 特斯拉股價(jià)大跌15%:Robotaxi離落地還差一個(gè)蘿卜快跑
- 4 馬斯克給的“驚喜”夠嗎?
- 5 打完“價(jià)格戰(zhàn)”,大模型還要比什么?
- 6 馬斯克致敬“國(guó)產(chǎn)蘿卜”?
- 7 神經(jīng)網(wǎng)絡(luò),誰(shuí)是盈利最強(qiáng)企業(yè)?
- 8 比蘋果偉大100倍!真正改寫人類歷史的智能產(chǎn)品降臨
- 9 諾獎(jiǎng)進(jìn)入“AI時(shí)代”,人類何去何從?
- 10 Open AI融資后成萬(wàn)億獨(dú)角獸,AI人才之爭(zhēng)開(kāi)啟
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市