動態(tài)分區(qū)分配算法有哪幾種?
本期是操作系統(tǒng)開胃菜,既然是開胃菜那字數少一點好了哈哈,就先來21 道題,16213 個字好了。
還有本來想等到《逆襲進大廠》系列出完之后再放出 PDF 的,可很多人讓我先出個第一版先看著…..
一開始我是拒絕的,可真的太多人跟我說了,考慮到最近金三銀四以及春招找工作期間很多人都需要這份資料,emm…
沒辦法,先出第一期好了。
以下是本期目錄,看看你會多少。
閑話少敘,開車開車!
1、進程、線程和協(xié)程的區(qū)別和聯(lián)系
1、進程是資源調度的基本單位,運行一個可執(zhí)行程序會創(chuàng)建一個或多個進程,進程就是運行起來的可執(zhí)行程序
2、線程是程序執(zhí)行的基本單位,是輕量級的進程。每個進程中都有唯一的主線程,且只能有一個,主線程和進程是相互依存的關系,主線程結束進程也會結束。多提一句:協(xié)程是用戶態(tài)的輕量級線程,線程內部調度的基本單位
2、線程與進程的比較
1、線程啟動速度快,輕量級
2、線程的系統(tǒng)開銷小
3、線程使用有一定難度,需要處理數據一致性問題
4、同一線程共享的有堆、全局變量、靜態(tài)變量、指針,引用、文件等,而獨自占有棧
3、一個進程可以創(chuàng)建多少線程,和什么有關?
理論上,一個進程可用虛擬空間是2G,默認情況下,線程的棧的大小是1MB,所以理論上最多只能創(chuàng)建2048個線程。如果要創(chuàng)建多于2048的話,必須修改編譯器的設置。
因此,一個進程可以創(chuàng)建的線程數由可用虛擬空間和線程的棧的大小共同決定,只要虛擬空間足夠,那么新線程的建立就會成功。如果需要創(chuàng)建超過2K以上的線程,減小你線程棧的大小就可以實現(xiàn)了,雖然在一般情況下,你不需要那么多的線程。過多的線程將會導致大量的時間浪費在線程切換上,給程序運行效率帶來負面影響。
4、外中斷和異常有什么區(qū)別?
外中斷是指由 CPU 執(zhí)行指令以外的事件引起,如 I/O 完成中斷,表示設備輸入/輸出處理已經完成,處理器能夠發(fā)送下一個輸入/輸出請求。此外還有時鐘中斷、控制臺中斷等。
而異常時由 CPU 執(zhí)行指令的內部事件引起,如非法操作碼、地址越界、算術溢出等。
5、進程線程模型你知道多少?
對于進程和線程的理解和把握可以說基本奠定了對系統(tǒng)的認知和把控能力。其核心意義絕不僅僅是“線程是調度的基本單位,進程是資源分配的基本單位”這么簡單。
多線程
我們這里討論的是用戶態(tài)的多線程模型,同一個進程內部有多個線程,所有的線程共享同一個進程的內存空間,進程中定義的全局變量會被所有的線程共享,比如有全局變量int i = 10,這一進程中所有并發(fā)運行的線程都可以讀取和修改這個i的值,而多個線程被CPU調度的順序又是不可控的,所以對臨界資源的訪問尤其需要注意安全。
我們必須知道,做一次簡單的i = i + 1在計算機中并不是原子操作,涉及內存取數,計算和寫入內存幾個環(huán)節(jié),而線程的切換有可能發(fā)生在上述任何一個環(huán)節(jié)中間,所以不同的操作順序很有可能帶來意想不到的結果。
但是,雖然線程在安全性方面會引入許多新挑戰(zhàn),但是線程帶來的好處也是有目共睹的。首先,原先順序執(zhí)行的程序(暫時不考慮多進程)可以被拆分成幾個獨立的邏輯流,這些邏輯流可以獨立完成一些任務(最好這些任務是不相關的)。
比如 QQ 可以一個線程處理聊天一個線程處理上傳文件,兩個線程互不干涉,在用戶看來是同步在執(zhí)行兩個任務,試想如果線性完成這個任務的話,在數據傳輸完成之前用戶聊天被一直阻塞會是多么尷尬的情況。
對于線程,我認為弄清以下兩點非常重要:
線程之間有無先后訪問順序(線程依賴關系)
多個線程共享訪問同一變量(同步互斥問題)
另外,我們通常只會去說同一進程的多個線程共享進程的資源,但是每個線程特有的部分卻很少提及,除了標識線程的tid,每個線程還有自己獨立的?臻g,線程彼此之間是無法訪問其他線程棧上內容的。
而作為處理機調度的最小單位,線程調度只需要保存線程棧、寄存器數據和PC即可,相比進程切換開銷要小很多。
線程相關接口不少,主要需要了解各個參數意義和返回值意義。
線程創(chuàng)建和結束
背景知識:
在一個文件內的多個函數通常都是按照main函數中出現(xiàn)的順序來執(zhí)行,但是在分時系統(tǒng)下,我們可以讓每個函數都作為一個邏輯流并發(fā)執(zhí)行,最簡單的方式就是采用多線程策略。在main函數中調用多線程接口創(chuàng)建線程,每個線程對應特定的函數(操作),這樣就可以不按照main函數中各個函數出現(xiàn)的順序來執(zhí)行,避免了忙等的情況。線程基本操作的接口如下。
相關接口:
創(chuàng)建線程:int pthread_create(pthread_t *pthread, const pthread_attr_t *attr, void (start_routine)(void *), void *agr);
創(chuàng)建一個新線程,pthread和start_routine不可或缺,分別用于標識線程和執(zhí)行體入口,其他可以填NULL。
pthread:用來返回線程的tid,*pthread值即為tid,類型pthread_t == unsigned long int。
attr:指向線程屬性結構體的指針,用于改變所創(chuàng)線程的屬性,填NULL使用默認值。
start_routine:線程執(zhí)行函數的首地址,傳入函數指針。
arg:通過地址傳遞來傳遞函數參數,這里是無符號類型指針,可以傳任意類型變量的地址,在被傳入函數中先強制類型轉換成所需類型即可。
獲得線程ID:pthread_t pthread_self();
調用時,會打印線程ID。
等待線程結束:int pthread_join(pthread_t tid, void** retval);
主線程調用,等待子線程退出并回收其資源,類似于進程中wait/waitpid回收僵尸進程,調用pthread_join的線程會被阻塞。
tid:創(chuàng)建線程時通過指針得到tid值。
retval:指向返回值的指針。
結束線程:pthread_exit(void *retval);
子線程執(zhí)行,用來結束當前線程并通過retval傳遞返回值,該返回值可通過pthread_join獲得。
retval:同上。
分離線程:int pthread_detach(pthread_t tid);
主線程、子線程均可調用。主線程中pthread_detach(tid),子線程中pthread_detach(pthread_self()),調用后和主線程分離,子線程結束時自己立即回收資源。
tid:同上。
線程屬性值修改
背景知識:
線程屬性對象類型為pthread_attr_t,結構體定義如下:
typedef struct{
int etachstate; // 線程分離的狀態(tài)
int schedpolicy; // 線程調度策略
struct sched_param schedparam; // 線程的調度參數
int inheritsched; // 線程的繼承性
int scope; // 線程的作用域
// 以下為線程棧的設置
size_t guardsize; // 線程棧末尾警戒緩沖大小
int stackaddr_set; // 線程的棧設置
void * stackaddr; // 線程棧的位置
size_t stacksize; // 線程棧大小
}pthread_arrt_t;
相關接口:
對上述結構體中各參數大多有:pthread_attr_get()和pthread_attr_set()系統(tǒng)調用函數來設置和獲取。這里不一一羅列。
多進程
每一個進程是資源分配的基本單位。
進程結構由以下幾個部分組成:代碼段、堆棧段、數據段。代碼段是靜態(tài)的二進制代碼,多個程序可以共享。
實際上在父進程創(chuàng)建子進程之后,父、子進程除了pid外,幾乎所有的部分幾乎一樣。
父、子進程共享全部數據,但并不是說他們就是對同一塊數據進行操作,子進程在讀寫數據時會通過寫時復制機制將公共的數據重新拷貝一份,之后在拷貝出的數據上進行操作。
如果子進程想要運行自己的代碼段,還可以通過調用execv()函數重新加載新的代碼段,之后就和父進程獨立開了。
我們在shell中執(zhí)行程序就是通過shell進程先fork()一個子進程再通過execv()重新加載新的代碼段的過程。
進程創(chuàng)建與結束
背景知識:
進程有兩種創(chuàng)建方式,一種是操作系統(tǒng)創(chuàng)建的一種是父進程創(chuàng)建的。從計算機啟動到終端執(zhí)行程序的過程為:0號進程 -> 1號內核進程 -> 1號用戶進程(init進程) -> getty進程 -> shell進程 -> 命令行執(zhí)行進程。所以我們在命令行中通過 ./program執(zhí)行可執(zhí)行文件時,所有創(chuàng)建的進程都是shell進程的子進程,這也就是為什么shell一關閉,在shell中執(zhí)行的進程都自動被關閉的原因。從shell進程到創(chuàng)建其他子進程需要通過以下接口。
相關接口:
創(chuàng)建進程:pid_t fork(void);
返回值:出錯返回-1;父進程中返回pid > 0;子進程中pid == 0
結束進程:void exit(int status);
status是退出狀態(tài),保存在全局變量中S?,通常0表示正常退出。
獲得PID:pid_t getpid(void);
返回調用者pid。
獲得父進程PID:pid_t getppid(void);
返回父進程pid。
其他補充:
正常退出方式:exit()、_exit()、return(在main中)。
exit()和_exit()區(qū)別:exit()是對__exit()的封裝,都會終止進程并做相關收尾工作,最主要的區(qū)別是_exit()函數關閉全部描述符和清理函數后不會刷新流,但是exit()會在調用_exit()函數前刷新數據流。
return和exit()區(qū)別:exit()是函數,但有參數,執(zhí)行完之后控制權交給系統(tǒng)。return若是在調用函數中,執(zhí)行完之后控制權交給調用進程,若是在main函數中,控制權交給系統(tǒng)。
異常退出方式:abort()、終止信號。
Linux進程控制
進程地址空間(地址空間)
虛擬存儲器為每個進程提供了獨占系統(tǒng)地址空間的假象。
盡管每個進程地址空間內容不盡相同,但是他們的都有相似的結構。X86 Linux進程的地址空間底部是保留給用戶程序的,包括文本、數據、堆、棧等,其中文本區(qū)和數據區(qū)是通過存儲器映射方式將磁盤中可執(zhí)行文件的相應段映射至虛擬存儲器地址空間中。
有一些"敏感"的地址需要注意下,對于32位進程來說,代碼段從0x08048000開始。從0xC0000000開始到0xFFFFFFFF是內核地址空間,通常情況下代碼運行在用戶態(tài)(使用0x00000000 ~ 0xC00000000的用戶地址空間),當發(fā)生系統(tǒng)調用、進程切換等操作時CPU控制寄存器設置模式位,進入內和模式,在該狀態(tài)(超級用戶模式)下進程可以訪問全部存儲器位置和執(zhí)行全部指令。
也就說32位進程的地址空間都是4G,但用戶態(tài)下只能訪問低3G的地址空間,若要訪問3G ~ 4G的地址空間則只有進入內核態(tài)才行。
進程控制塊(處理機)
進程的調度實際就是內核選擇相應的進程控制塊,被選擇的進程控制塊中包含了一個進程基本的信息。
上下文切換
內核管理所有進程控制塊,而進程控制塊記錄了進程全部狀態(tài)信息。每一次進程調度就是一次上下文切換,所謂的上下文本質上就是當前運行狀態(tài),主要包括通用寄存器、浮點寄存器、狀態(tài)寄存器、程序計數器、用戶棧和內核數據結構(頁表、進程表、文件表)等。
進程執(zhí)行時刻,內核可以決定搶占當前進程并開始新的進程,這個過程由內核調度器完成,當調度器選擇了某個進程時稱為該進程被調度,該過程通過上下文切換來改變當前狀態(tài)。
一次完整的上下文切換通常是進程原先運行于用戶態(tài),之后因系統(tǒng)調用或時間片到切換到內核態(tài)執(zhí)行內核指令,完成上下文切換后回到用戶態(tài),此時已經切換到進程B。

請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
-
10月23日火熱報名中>> 2025是德科技創(chuàng)新技術峰會
-
10月23日立即報名>> Works With 開發(fā)者大會深圳站
-
11月7日立即參評>> 【評選】維科杯·OFweek 2025(第十屆)物聯(lián)網行業(yè)年度評選
-
即日-11.25立即下載>>> 費斯托白皮書《柔性:汽車生產未來的關鍵》
-
11月27日立即報名>> 【工程師系列】汽車電子技術在線大會
-
11月28日立即下載>> 【白皮書】精準洞察 無線掌控——283FC智能自檢萬用表
-
8 每日AI全球觀察
- 1 特斯拉工人被故障機器人打成重傷,索賠3.6億
- 2 【行業(yè)深度研究】退居幕后四年后,張一鳴終于把算法公司變成AI公司?
- 3 AI 時代,阿里云想當“安卓” ,那誰是“蘋果”?
- 4 拐點已至!匯川領跑工控、埃斯頓份額第一、新時達海爾賦能扭虧為盈
- 5 硬剛英偉達!華為發(fā)布全球最強算力超節(jié)點和集群
- 6 隱退4年后,張一鳴久違現(xiàn)身!互聯(lián)網大佬正集體殺回
- 7 L3自動駕駛延期,逼出車企技術自我淘汰
- 8 谷歌“香蕉”爆火啟示:國產垂類AI的危機還是轉機?
- 9 00后華裔女生靠兩部AI電影狂賺7.8億人民幣,AI正式進軍好萊塢
- 10 機器人9月大事件|3家國產機器人沖刺IPO,行業(yè)交付與融資再創(chuàng)新高!
- 生產部總監(jiān) 廣東省/廣州市
- 資深管理人員 廣東省/江門市
- Regional Sales Manager 廣東省/深圳市
- 銷售總監(jiān) 廣東省/深圳市
- 結構工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 自動化高級工程師 廣東省/深圳市
- 技術專家 廣東省/江門市
- 激光器高級銷售經理 上海市/虹口區(qū)
- 封裝工程師 北京市/海淀區(qū)