1. 馮諾依曼體系結(jié)構(gòu)
馮·諾依曼結(jié)構(gòu)也稱普林斯頓結(jié)構(gòu),是一種將程序指令存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器合并在一起的存儲(chǔ)器結(jié)構(gòu)。數(shù)學(xué)家馮·諾依曼提出了計(jì)算機(jī)制造的三個(gè)基本原則,即采用二進(jìn)制邏輯、程序存儲(chǔ)執(zhí)行以及計(jì)算機(jī)由五個(gè)部分組成(運(yùn)算器、控制器、存儲(chǔ)器、輸入設(shè)備、輸出設(shè)備
),這套理論被稱為馮·諾依曼體系結(jié)構(gòu)。
這里我們來介紹一下組成馮諾依曼體系結(jié)構(gòu)的五個(gè)部分:
輸入設(shè)備:鍵盤、攝像頭、網(wǎng)卡、磁盤等
輸出設(shè)備:顯示器、磁盤、網(wǎng)卡、聲卡音響等
存儲(chǔ)器:內(nèi)存(掉電易失)
運(yùn)算器和控制器:CPU
關(guān)于馮諾依曼,我們必須強(qiáng)調(diào)幾點(diǎn):
- 這里的存儲(chǔ)器指的是內(nèi)存
- 不考慮緩存情況,這里的CPU能且只能對(duì)內(nèi)存進(jìn)行讀寫,不能訪問外設(shè)(輸入或輸出設(shè)備)
- 外設(shè)(輸入或輸出設(shè)備)要輸入或者輸出數(shù)據(jù),也只能寫入內(nèi)存或者從內(nèi)存中讀取。
我們知道,我們的數(shù)據(jù)需要先從磁盤加載到內(nèi)存中,然后由CPU讀取并進(jìn)行計(jì)算,將計(jì)算的結(jié)果再次加載到內(nèi)存中,最后再由內(nèi)存寫入磁盤,通過輸出設(shè)備將數(shù)據(jù)交給我們。那么,為什么CPU為什么不能直接訪問外設(shè)呢?
其實(shí)原因也很簡(jiǎn)單,輸入輸出設(shè)備稱之為外圍設(shè)備,外設(shè)一般是很慢的,比如說磁盤,相對(duì)于內(nèi)存,他的速度是非常慢的,但CPU的計(jì)算速度確是非??斓?。就好比從磁盤的讀取速度很慢,但是CPU的計(jì)算速度卻很快,但是整體的速度還是以磁盤的讀取速度為主的,所以整體效率就以外設(shè)為主。
所以在這里得出了兩個(gè)結(jié)論:
- 在數(shù)據(jù)層面上,一般CPU不和外設(shè)直接溝通,而是直接和內(nèi)存打交道。
- 在數(shù)據(jù)層面上,外設(shè)指揮和內(nèi)存打交道。
所以說,程序的運(yùn)行必須加載到內(nèi)存中,因?yàn)镃PU想要執(zhí)行我們的程序,訪問我們的數(shù)據(jù),就必須從內(nèi)存中讀取,這是馮諾依曼體系結(jié)構(gòu)規(guī)定的。
?? 那么,在硬件層面,單機(jī)和跨主機(jī)之間的數(shù)據(jù)流是如何流向的呢?
對(duì)馮諾依曼的理解,不能停留在概念上,要深入到對(duì)軟件數(shù)據(jù)流理解上,那么,當(dāng)你從登錄上qq開始和某位朋友聊天開始,整個(gè)信息是如何在體系結(jié)構(gòu)中流動(dòng)的?
當(dāng)我和我的朋友同時(shí)打開QQ時(shí),我們的QQ其實(shí)已經(jīng)被加載到內(nèi)存中了,然后當(dāng)我們?cè)趯?duì)話框中輸入消息時(shí),我們的數(shù)據(jù)已經(jīng)被輸入到內(nèi)存中了,下面我們的數(shù)據(jù)在內(nèi)存中被加密計(jì)算,計(jì)算完之后將數(shù)據(jù)返回到內(nèi)存,然后顯示到輸出設(shè)備,也就是我們的顯示器和網(wǎng)卡上,這時(shí)我們就可以在顯示器上看到我們所發(fā)送的消息了。
緊接著,我們的數(shù)據(jù)還會(huì)通過網(wǎng)卡輸入到對(duì)方的電腦上,對(duì)方通過網(wǎng)卡接收到數(shù)據(jù)后,加載到內(nèi)存中,然后通過CPU將數(shù)據(jù)進(jìn)行解密操作并寫回內(nèi)存,最后通過輸出設(shè)備顯示到對(duì)方的顯示器上。
2. 操作系統(tǒng)
操作系統(tǒng)是一款進(jìn)行軟硬件資源管理的軟件
,在這里我們先來解釋一下,為什么操作系統(tǒng)要對(duì)軟硬件進(jìn)行管理呢?
其實(shí)是因?yàn)椋?mark>操作系統(tǒng)對(duì)下要管理好軟硬件資源,對(duì)上需要給用戶提供良好(安全、穩(wěn)定、高效、功能豐富等)的執(zhí)行環(huán)境。
那么我們應(yīng)該如何理解操作系統(tǒng)對(duì)硬件做管理呢?其實(shí),管理的本質(zhì)就是對(duì)數(shù)據(jù)進(jìn)行管理,管理的方法是:先描述、后組織。
?? 管理的本質(zhì)是對(duì)數(shù)據(jù)進(jìn)行管理
對(duì)于這一點(diǎn),我們應(yīng)該如何理解呢?我們可以以學(xué)校為例:假設(shè)學(xué)校只有校長(zhǎng)、輔導(dǎo)員和學(xué)生。那么在這里,校長(zhǎng)就是我們的管理者,同時(shí)也是做決策的人,而輔導(dǎo)員呢就是執(zhí)行者,最后輔導(dǎo)員把決策交給我們學(xué)生,學(xué)生才是真正的被管理者。
因?yàn)楣芾淼谋举|(zhì)就是數(shù)據(jù)進(jìn)行管理,但在這里我們需要考慮的是,管理者是如何拿到被管理者的數(shù)據(jù)的呢?就好比說,校長(zhǎng)是如何拿到我們學(xué)生的數(shù)據(jù)的呢?其實(shí)也很簡(jiǎn)單,通過輔導(dǎo)員拿到的了。而校長(zhǎng)只要管理好我們學(xué)生的這些數(shù)據(jù),就能將學(xué)生管理起來了,所以管理的本質(zhì)就是對(duì)數(shù)據(jù)做管理。
?? 管理的方法是先描述、后組織
這里我們可以想一下,學(xué)校的學(xué)生那么多,校長(zhǎng)是如何管理的呢?這里我們提出了一種方法,叫做 ‘先描述、后組織’,
先描述
,就好比先將將被管理者的數(shù)據(jù)抽象成一個(gè)結(jié)構(gòu)體(類),后組織
,就是使用各種數(shù)據(jù)結(jié)構(gòu)將數(shù)據(jù)管理起來,這里我們可以先將學(xué)生的各種信息定義一個(gè)結(jié)構(gòu)體,然后,將學(xué)生們通過鏈表鏈接起來,那么現(xiàn)在對(duì)學(xué)生數(shù)據(jù)做管理就變成了,對(duì)鏈表的管理。
當(dāng)然了,對(duì)應(yīng)到我們的計(jì)算機(jī)中,操作系統(tǒng)
就相當(dāng)于我們的管理者,而硬件驅(qū)動(dòng)
就相當(dāng)于我們的執(zhí)行者,而硬件(軟件)
就是我們被管理者。
當(dāng)然了,我們的操作系統(tǒng)也是不相信任何人的,為了保護(hù)操作系統(tǒng)不受到任何的侵害,但是又必須又必須給上層用戶提供服務(wù),在用戶和操作系統(tǒng)之間有一層系統(tǒng)調(diào)用接口,但由于系統(tǒng)調(diào)用接口的使用成本很高,所以相關(guān)人員就在系統(tǒng)調(diào)用上面進(jìn)行了二次軟件開發(fā),例如:圖形化界面、shell和工具集等。
系統(tǒng)調(diào)用和庫(kù)函數(shù):
- 在開發(fā)角度,操作系統(tǒng)對(duì)外會(huì)表現(xiàn)為一個(gè)整體,但是會(huì)暴露自己的部分接口,供上層開發(fā)使用,這部分由操作系統(tǒng)提供的接口,叫做系統(tǒng)調(diào)用。
- 系統(tǒng)調(diào)用在使用上,功能比較基礎(chǔ),對(duì)用戶的要求相對(duì)也比較高,所以,有心的開發(fā)者可以對(duì)部分系統(tǒng)調(diào)用進(jìn)行適度封裝,從而形成庫(kù),有了庫(kù),就很有利于更上層用戶或者開發(fā)者進(jìn)行二次開發(fā)。
計(jì)算機(jī)的體系結(jié)構(gòu)圖
3. 進(jìn)程
進(jìn)程的基本概念
進(jìn)程
在課本中的描述一般為:程序的一個(gè)執(zhí)行實(shí)例,正在執(zhí)行的程序,或者是一個(gè)程序運(yùn)行起來(程序被加載到內(nèi)存)就是進(jìn)程,進(jìn)程的內(nèi)核觀點(diǎn)是擔(dān)當(dāng)分配系統(tǒng)資源(CPU時(shí)間,內(nèi)存)的實(shí)體。但是這些概念都很膚淺,我們應(yīng)該如何去描述一個(gè)進(jìn)程呢?
?? 描述進(jìn)程
- 進(jìn)程信息被放在一個(gè)叫做進(jìn)程控制塊的數(shù)據(jù)結(jié)構(gòu)中,可以理解為進(jìn)程屬性的集合。
- 課本上稱之為PCB(process control block), Linux操作系統(tǒng)下的PCB是:
task_struct
當(dāng)我們把多個(gè)程序加載到內(nèi)存中時(shí),操作系統(tǒng)會(huì)對(duì)這些程序進(jìn)行先描述,后組織。那么操作系統(tǒng)是如何對(duì)我們的程序進(jìn)行描述和組織的呢?
我們將寫好的代碼編譯鏈接形成可執(zhí)行程序存放在磁盤上,然后我們運(yùn)行這個(gè)程序時(shí),需要先將這個(gè)程序加載到內(nèi)存中,然后通過CPU進(jìn)行運(yùn)算。當(dāng)我們的程序加載到內(nèi)存中時(shí),操作系統(tǒng)會(huì)對(duì)我們的程序進(jìn)行管理,對(duì)程序的管理方法我們?cè)谏厦嬉蔡峒暗搅耍?code>先描述,在組織。
操作系統(tǒng)在對(duì)我們的進(jìn)程進(jìn)行先描述,后組織的時(shí)候,會(huì)先將我們的程序的共有屬性創(chuàng)建一個(gè)結(jié)構(gòu)體,然后對(duì)我們的每一個(gè)進(jìn)程創(chuàng)建一個(gè)結(jié)構(gòu)體對(duì)象,這就是先描述
的過程。接下來我們的操作系統(tǒng)會(huì)使用特性的數(shù)據(jù)結(jié)構(gòu)(比如鏈表)將我們的結(jié)構(gòu)體對(duì)象組織起來,這就是后組織
的過程。然后我們的操作系統(tǒng)對(duì)進(jìn)程的管理就會(huì)轉(zhuǎn)換成對(duì)特定數(shù)據(jù)結(jié)構(gòu)的管理。當(dāng)然了,這個(gè)描述和組織進(jìn)程的東西就被稱為進(jìn)程控制塊(PCB)。
所以,在這里我們也引出了進(jìn)程真正的概念:進(jìn)程=內(nèi)核關(guān)于進(jìn)程的相關(guān)數(shù)據(jù)結(jié)構(gòu)+當(dāng)前進(jìn)程的代碼和數(shù)據(jù)。
進(jìn)程控制塊(PCB) 是我們操作系統(tǒng)用來描述進(jìn)程的工具,他包含了進(jìn)程屬性的集合。在Linux中描述進(jìn)程的結(jié)構(gòu)體叫做task_struct。他是Linux內(nèi)核的一種數(shù)據(jù)結(jié)構(gòu),它會(huì)被裝載到
RAM(內(nèi)存)
里并且包含著進(jìn)程的信息。
下面我們看一下task_ struct內(nèi)容分類:
- 標(biāo)示符: 描述本進(jìn)程的唯一標(biāo)示符,用來區(qū)別其他進(jìn)程。
- 狀態(tài): 任務(wù)狀態(tài),退出代碼,退出信號(hào)等。
- 優(yōu)先級(jí): 相對(duì)于其他進(jìn)程的優(yōu)先級(jí)。
- 程序計(jì)數(shù)器: 程序中即將被執(zhí)行的下一條指令的地址。
- 內(nèi)存指針: 包括程序代碼和進(jìn)程相關(guān)數(shù)據(jù)的指針,還有和其他進(jìn)程共享的內(nèi)存塊的指針
- 上下文數(shù)據(jù): 進(jìn)程執(zhí)行時(shí)處理器的寄存器中的數(shù)據(jù)[休學(xué)例子,要加圖CPU,寄存器]。
- I/ O狀態(tài)信息: 包括顯示的I/O請(qǐng)求,分配給進(jìn)程的I/ O設(shè)備和被進(jìn)程使用的文件列表。
- 記賬信息: 可能包括處理器時(shí)間總和,使用的時(shí)鐘數(shù)總和,時(shí)間限制,記賬號(hào)等。
- 其他信息
查看進(jìn)程和殺死進(jìn)程
?? 查看進(jìn)程
再查看進(jìn)程之前我們需要先創(chuàng)建寫一段普通的C語(yǔ)言代碼:
查看進(jìn)程有兩種方式,這里我們先來講解第一種:
ps ajx | head -1 && ps ajx | grep '進(jìn)程名'
當(dāng)然了我們需要先將我們的程序運(yùn)行起來:
這里我們還可以看到在我們的myproc進(jìn)程的下面還有一個(gè)grep進(jìn)程,這是因?yàn)間rep指令也是一個(gè)進(jìn)程,進(jìn)程在調(diào)度的時(shí)候是具有動(dòng)態(tài)屬性的。這里我們還需要解釋一個(gè)概念那就是PID
和PPID
的概念,操作系統(tǒng)里指進(jìn)程識(shí)別號(hào),也就是進(jìn)程標(biāo)識(shí)符
。操作系統(tǒng)里每打開一個(gè)程序都會(huì)創(chuàng)建一個(gè)進(jìn)程ID,即PID。 當(dāng)然了,PPID就是父進(jìn)程的進(jìn)程ID號(hào)。
查看進(jìn)程的第二種方式:通過查看進(jìn)程目錄 ls /proc
來查看進(jìn)程
當(dāng)然了我們還可以直接到==/proc/進(jìn)程pid==目錄下去查看進(jìn)程對(duì)應(yīng)的可執(zhí)行程序。
?? 殺死進(jìn)程
我們要結(jié)束我們的進(jìn)程可以有兩種方法:直接按ctrl+c結(jié)束進(jìn)程或者殺死進(jìn)程。殺死進(jìn)程需要的命令是:kill -9 進(jìn)程標(biāo)識(shí)符
父進(jìn)程和子進(jìn)程
上面我們已經(jīng)介紹了父進(jìn)程和子進(jìn)程有各自的進(jìn)程ID,但是究竟什么是父進(jìn)程呢?什么又是子進(jìn)程呢?其實(shí),我們平常所寫的進(jìn)程都是由bash
這個(gè)父進(jìn)程來創(chuàng)建的,bash其實(shí)就是shell外殼,shell為了防止自身奔潰,一幫會(huì)通過派生子進(jìn)程的方式去執(zhí)行我們的指令。
我們可以通過getpid
和getppid
函數(shù)來獲取當(dāng)前進(jìn)程的ID和當(dāng)前進(jìn)程父進(jìn)程的ID。下面我們來看一下這兩個(gè)函數(shù):
這里我們修改一下我們的程序,看一下父進(jìn)程和子進(jìn)程的ID:
如果我們把我們的程序終止掉,然后再次運(yùn)行的時(shí)候,就會(huì)發(fā)現(xiàn)子進(jìn)程的ID一直在變,而父進(jìn)程的ID卻不變。那么我們現(xiàn)在來看一下這個(gè)父進(jìn)程究竟是什么?
這是我們就可以恍然大悟了,原來該父進(jìn)程就是bash,bash通過創(chuàng)建子進(jìn)程的方式來運(yùn)行我們的程序,那么shell是如何創(chuàng)建子進(jìn)程的呢?下面就讓我們來認(rèn)識(shí)一下如何創(chuàng)建子進(jìn)程。
通過系統(tǒng)調(diào)用創(chuàng)建子進(jìn)程
我們先通過 man fork 來認(rèn)識(shí)一下fork
函數(shù):
fork函數(shù)的返回值是fork函數(shù)的重點(diǎn),如果子進(jìn)程創(chuàng)建成功,fork函數(shù)給父進(jìn)程返回子進(jìn)程的id,給子進(jìn)程返回0,如果子進(jìn)程創(chuàng)建失敗將會(huì)給父進(jìn)程返回-1。
這里我們先修改一下我們的代碼:
但是這個(gè)代碼為什么可以既執(zhí)行if里面的語(yǔ)句,又可以執(zhí)行if else里面的代碼呢?
結(jié)論:
- fork之后,執(zhí)行流會(huì)變成2個(gè)執(zhí)行流。
- fork之后,誰(shuí)先運(yùn)行由調(diào)度器決定。
- fork之后的代碼共享,通常通過
if
和elseif
來進(jìn)行執(zhí)行流分流。
下面我們?cè)賮砜匆粋€(gè)更離譜的事情,我們將代碼中的內(nèi)容做出如下修改:
以上問題我們都可以歸結(jié)為三點(diǎn):
- fork做了什么?
- fork是如何看待代碼和數(shù)據(jù)的?
- fork如何理解兩個(gè)返回值問題?
?? fork做了什么?
子進(jìn)程會(huì)創(chuàng)建一份獨(dú)立的pcb結(jié)構(gòu),但子進(jìn)程的pcb的大部分屬性都是以父進(jìn)程為模板進(jìn)行拷貝的,當(dāng)然了對(duì)于PID和PPID這些值是不能拷貝的。
?? fork是如何看待代碼和數(shù)據(jù)的?
進(jìn)程在運(yùn)行的時(shí)候,是具有獨(dú)立性的,當(dāng)然父子進(jìn)程再運(yùn)行的時(shí)候也是具有獨(dú)立性的,如果我們父子進(jìn)程同時(shí)運(yùn)行但我們把其中任意一個(gè)進(jìn)程殺死后,并不會(huì)影響另一個(gè)進(jìn)程。當(dāng)然如果父子進(jìn)程中有相同的變量,但我們修改父進(jìn)程或子進(jìn)程中的任意一個(gè)數(shù)據(jù)時(shí),操作系統(tǒng)會(huì)在當(dāng)前進(jìn)程中觸發(fā)
寫時(shí)拷貝
。
?? fork是如何理解兩個(gè)返回值問題的?
文章來源:http://www.zghlxwxcb.cn/news/detail-792210.html
當(dāng)我們的函數(shù)執(zhí)行return功能之前其實(shí)函數(shù)中的主體部分就已經(jīng)完成了,但是return也是一條語(yǔ)句,在這之前子進(jìn)程已經(jīng)被創(chuàng)建,甚至可能已經(jīng)被調(diào)度,我們?cè)趫?zhí)行return時(shí),父進(jìn)程可以被調(diào)度執(zhí)行一次,而子進(jìn)程也有它的執(zhí)行流,所以return也會(huì)被調(diào)度執(zhí)行一次。所以一條return就被執(zhí)行了兩次,好像讓我們看到了兩個(gè)返回值。文章來源地址http://www.zghlxwxcb.cn/news/detail-792210.html
到了這里,關(guān)于【Linux】操作系統(tǒng)&&進(jìn)程概念的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!