欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Unix/Linux fork隱藏的開(kāi)銷

 更新時(shí)間:2021年08月23日 15:21:45   作者:Linux閱碼場(chǎng)  
本文通過(guò)介紹Unix、fork的由來(lái)及早期狀態(tài),展開(kāi)其隱藏的開(kāi)銷,對(duì)此感興趣的小伙伴不要錯(cuò)過(guò)奧

一、fork的由來(lái)

fork的思想在UNIX出現(xiàn)幾年前就出現(xiàn)了,時(shí)間大概是1963年,這比UNIX在PDP-7上的第一個(gè)版本早了6年。
1963年,計(jì)算機(jī)科學(xué)家Melvin Conway(以Conway's Law聞名于世)寫(xiě)下一篇論文,正式提出了fork思想,
fork的思想最初是Conway作為一種 多處理器并行 的方案提出來(lái)的,這個(gè)想法非常有意思。簡(jiǎn)而言之,fork思想來(lái)源于流程圖。

我們看一個(gè)普通的流程圖:

你看,流程圖的分枝處,fork-叉子,多么形象!

一個(gè)流程圖上的分支點(diǎn)分裂出來(lái)的分支顯然是邏輯獨(dú)立的,這便是可并行的前提,于是它們便可以表現(xiàn)為不同的 處理進(jìn)程(process) 的形式,當(dāng)時(shí)的表達(dá)還只是“process”這個(gè)術(shù)語(yǔ),它還不是現(xiàn)代操作系統(tǒng)意義上的“進(jìn)程”的概念。

join同步點(diǎn)表現(xiàn)為多個(gè)并行處理的進(jìn)程由于某種原因不得不同步的點(diǎn),也就是多個(gè)并行流程匯合的點(diǎn),直到現(xiàn)在,在多線程編程中,這個(gè)點(diǎn)依然叫join。比如Java Thread的join方法以及pthread庫(kù)的pthread_join函數(shù)。

廣義來(lái)講,join也表示諸如臨界區(qū)等必須串行通過(guò)的點(diǎn), 減少join點(diǎn)的數(shù)量將會(huì)提高并行的效率。

我們來(lái)看看Conway論文中關(guān)于fork的原始圖示:

Conway在論文中的另一個(gè)創(chuàng)舉是,他將處理進(jìn)程(也就是后來(lái)操作系統(tǒng)中的process的概念)以及執(zhí)行該進(jìn)程的處理器(即CPU核)分離了開(kāi)來(lái),抽象出了schedule層。

大意是說(shuō)、“只要滿足系統(tǒng)中的活動(dòng)處理器數(shù)量是總處理器數(shù)量和并行處理進(jìn)程的最小值即可?!?這意味著調(diào)度程序可以將多處理器系統(tǒng)的所有處理器和系統(tǒng)所有處理進(jìn)程分別看作是統(tǒng)一的資源池和消費(fèi)者,執(zhí)行統(tǒng)一調(diào)度:

在UNIX引入fork之后,這種多處理器并行的設(shè)計(jì)思想就深入到了UNIX的核心。這個(gè)思想最終也影響了UNIX以及后來(lái)的Linux,直到現(xiàn)在。
關(guān)于這個(gè)設(shè)計(jì)思想為什么可以影響UNIX這么久,我想和Conway本人的“Conway's law”不無(wú)關(guān)系,在這個(gè)law中,他提到:Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.

二、早期UNIX的覆蓋(overlaying)技術(shù)

接下來(lái)看UNIX fork的另一個(gè)脈絡(luò),1969年最初的UNIX用一種在現(xiàn)在看來(lái)非常奇怪的方式運(yùn)行。

一般的資料都是從UNIX v6版本開(kāi)始講起,那個(gè)版本已經(jīng)是比較 “現(xiàn)代” 的版本了,所以很少有人能看到最初的UNIX是什么樣子的。即便是能查閱到的1970年的PDP-7上運(yùn)行的UNIX源碼,也是引入fork之后的版本,在那之前的最原始版本幾乎找不到了(你可能會(huì)說(shuō),那時(shí)的UNIX不叫UNIX,but who cares…)。

最初的UNIX是一個(gè)分時(shí)系統(tǒng),它只有兩個(gè)shell進(jìn)程,分別屬于兩個(gè)終端:

分時(shí)系統(tǒng)最初并不是基于進(jìn)程分時(shí)的,那時(shí)根本還沒(méi)有完整的進(jìn)程的概念,分時(shí)系統(tǒng)是針對(duì)終端分時(shí)的,而操作員坐在終端前,為了讓每個(gè)操作員在操作過(guò)程中感覺(jué)上是在獨(dú)占機(jī)器資源,每個(gè)終端享受一段時(shí)間的時(shí)間片,在該時(shí)間片內(nèi),該終端前的操作員完全享受機(jī)器,但是為了公平,超過(guò)了時(shí)間片,時(shí)間片就要給另一個(gè)終端。

就是這樣,最初的UNIX為了體現(xiàn)分時(shí)特性,實(shí)現(xiàn)了最少的兩個(gè)終端。注意,最初的UNIX沒(méi)有fork,沒(méi)有exec,甚至沒(méi)有多進(jìn)程的概念,為了實(shí)現(xiàn)分時(shí),系統(tǒng)中僅有兩個(gè)樸素的shell進(jìn)程。

事實(shí)上,最初的UNIX用只有兩個(gè)元素的表來(lái)容納所有進(jìn)程(顯然,這看起來(lái)好笑…),當(dāng)然,這里的 “表” 的概念也是抽象的樸素概念,因?yàn)楫?dāng)時(shí)的系統(tǒng)是用PDP-7的匯編寫(xiě)的,還沒(méi)有后來(lái)C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)。

我們現(xiàn)在考慮其中一個(gè)終端的shell進(jìn)程如何工作。馬上問(wèn)題就來(lái)了, 這個(gè)shell進(jìn)程如何執(zhí)行別的命令程序??

如果說(shuō)系統(tǒng)中最多只能容納兩個(gè)進(jìn)程,一個(gè)終端只有一個(gè)shell進(jìn)程的話,當(dāng)該終端的shell進(jìn)程執(zhí)行其它命令程序時(shí),它自己怎么辦?這個(gè)問(wèn)題得思考一會(huì)兒…

注意:不要用現(xiàn)代的眼光去評(píng)價(jià)1969年的初版UNIX,按照現(xiàn)代的眼光,執(zhí)行一個(gè)程序必然要生成一個(gè)新的進(jìn)程,顯然這在初版UNIX中并不正確。

答案是根本不用產(chǎn)生新的進(jìn)程,直接將命令程序的代碼載入內(nèi)存并 覆蓋 掉shell進(jìn)程的代碼即可!當(dāng)命令執(zhí)行完后,再用shell的代碼覆蓋掉命令程序的代碼,針對(duì)單獨(dú)的終端,系統(tǒng)其實(shí)一直在執(zhí)行下面的覆蓋循環(huán)(摘自論文的Process control 章節(jié)):

然而,在fork被引入U(xiǎn)NIX之前,事實(shí)就是這樣。一個(gè)終端上一直都是那一個(gè)進(jìn)程,一會(huì)兒它執(zhí)行shell的代碼,一會(huì)兒它執(zhí)行具體命令程序的代碼,以下是一個(gè)覆蓋程序的結(jié)構(gòu)(圖片來(lái)自《FreeBSD操作系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)》一書(shū)):

然而,當(dāng)時(shí)畢竟還沒(méi)有將這個(gè)邏輯封裝成exec系統(tǒng)調(diào)用,這些都是每一個(gè)進(jìn)程顯式完成的:

  • 對(duì)于shell執(zhí)行命令程序而言,shell自己執(zhí)行disk IO來(lái)載入命令程序覆蓋掉自身;
  • 對(duì)于命令程序執(zhí)行結(jié)束時(shí),exit調(diào)用內(nèi)部執(zhí)行disk IO載入shell程序。

exec邏輯是shell程序的一部分,由于它會(huì)被所有的命令程序所使用,該邏輯也被封裝到了exit調(diào)用中。

三、fork引入U(xiǎn)NIX前的表象

1963年Melvin Conway提出了fork思想,作為在多處理器中并行執(zhí)行進(jìn)程的一個(gè)手段。

1969年湯普森版UNIX僅有兩個(gè)shell進(jìn)程,使用覆蓋(overlaying)技術(shù)執(zhí)行命令。

截止目前,我們看到的表象是:

湯普森版UNIX沒(méi)有fork,沒(méi)有exec,沒(méi)有wait,僅有的庫(kù)函數(shù)般的exit也和現(xiàn)在的exit系統(tǒng)調(diào)用大相徑庭,顯然湯普森版UNIX并非一個(gè)多進(jìn)程系統(tǒng),而只是一個(gè)可以跑的簡(jiǎn)陋的兩終端分時(shí)系統(tǒng)!

1、UNIX fork的誕生

fork是如何引入U(xiǎn)NIX的呢?

這還要從采用覆蓋技術(shù)的湯普森版UNIX所固有的問(wèn)題說(shuō)起,還是看論文原文:

若要解決這些問(wèn)題,很簡(jiǎn)單的方案湯普森都想到了:

  • 保持shell進(jìn)程的駐留而不是銷毀。命令執(zhí)行時(shí),將其交換到磁盤(pán)便是了

很顯然,命令程序是不能覆蓋掉shell進(jìn)程了。解決方案是使用 “交換” 技術(shù)。

交換技術(shù)和覆蓋技術(shù)其實(shí)都是解決有限內(nèi)存的多進(jìn)程使用問(wèn)題的,不同點(diǎn)在于方向不同:

  • 覆蓋技術(shù)指的是用不同的進(jìn)程磁盤(pán)映像覆蓋當(dāng)前的進(jìn)程內(nèi)存映像。
  • 交換技術(shù)指的是用將進(jìn)程的內(nèi)存映像交換到磁盤(pán),載入一個(gè)別的進(jìn)程磁盤(pán)映像。

使用交換技術(shù)解決覆蓋的問(wèn)題,意味著要?jiǎng)?chuàng)建新的進(jìn)程:

  • 在新的進(jìn)程中執(zhí)行命令程序。

UNIX需要進(jìn)行改動(dòng),兩個(gè)配額的進(jìn)程表顯然不夠用了。當(dāng)然,解決方案也并不麻煩:

要講效率,創(chuàng)造不如抄襲,創(chuàng)建新進(jìn)程的最直接的就是copy當(dāng)前shell進(jìn)程,在copy的新進(jìn)程中執(zhí)行覆蓋,命令程序覆蓋copy的新進(jìn)程,而當(dāng)前的終端shell進(jìn)程則被交換到磁盤(pán)保得全身。

覆蓋和交換相結(jié)合了,UNIX離現(xiàn)代化更近了一步!

確定了copy當(dāng)前進(jìn)程的方案后,進(jìn)一步的問(wèn)題是如何來(lái)copy進(jìn)程。

現(xiàn)在要說(shuō)回fork了。

Conway提出fork思想后,馬上就有了fork的實(shí)現(xiàn)原型(正如Conway自己所說(shuō),他只是提出了一個(gè)可能造就存在的想法,并沒(méi)有實(shí)現(xiàn)它),Project Genie算是實(shí)現(xiàn)fork比較完善的系統(tǒng)之一了。

Project Genie系統(tǒng)的fork不僅僅是盲目地copy進(jìn)程,它對(duì)fork的過(guò)程擁有精細(xì)的控制權(quán),比如分配多大的內(nèi)存空間,copy哪些必要的資源等等。顯然,Project Genie的fork是沖著Conway的多處理器并行邏輯去的。

還是那句話,創(chuàng)造不如抄襲,UNIX若想實(shí)現(xiàn)進(jìn)程copy,有一個(gè)現(xiàn)成的模版就是Project Genie,但是Project Genie的fork對(duì)于UNIX太過(guò)復(fù)雜,太過(guò)精細(xì)化了,UNIX顯然用不到這些精細(xì)的控制, UNIX僅僅是想讓fork出來(lái)的新進(jìn)程被覆蓋,而不是讓它去執(zhí)行什么多處理器上的并行邏輯。

換句話說(shuō),UNIX只是借用了fork的copy邏輯的實(shí)現(xiàn),來(lái)完成一件別的事。

于是,UNIX非常粗暴的實(shí)現(xiàn)了fork!即完全copy父進(jìn)程,這就是直到現(xiàn)在我們依然在使用的fork系統(tǒng)調(diào)用:

投機(jī)取巧:

  • fork本來(lái)就不是讓你用來(lái)覆蓋新進(jìn)程的,不然為何多此一舉。fork是讓你來(lái)分解程序流程得以并行處理的。

UNIX fork就此誕生!

我們?cè)俅位仡櫼幌耈NIX fork誕生之前的景象:

再來(lái)看看fork誕生之后的景象:

于是UNIX正式邁開(kāi)了現(xiàn)代化建設(shè)的步伐,一直走到了今天。

2、UNIX fork-exec

關(guān)于exec,故事沒(méi)什么好講的,它事實(shí)上就是關(guān)于上述覆蓋邏輯的封裝,此后程序員不必自己寫(xiě)覆蓋邏輯了,直接調(diào)用exec系統(tǒng)調(diào)用即可。

于是經(jīng)典的UNIX fork-exec序列便形成了。

3、UNIX fork/exec/exit/wait

值得一提的是,fork被引入U(xiǎn)NIX后,exit的語(yǔ)義發(fā)生了巨大的改變。

在原始的1969年湯普森版UNIX中,由于每一個(gè)終端有且僅有一個(gè)進(jìn)程,這意味著覆蓋永遠(yuǎn)是在shell程序和某個(gè)命令程序之間進(jìn)行的:

  • shell執(zhí)行命令A(yù):命令程序A覆蓋內(nèi)存中的shell代碼。
  • 命令A(yù)執(zhí)行結(jié)束:shell覆蓋結(jié)束的命令A(yù)的內(nèi)存代碼。

然而,在fork被引入后,雖然shell執(zhí)行某個(gè)命令依然是特定的命令程序覆蓋fork出來(lái)的shell子進(jìn)程,但是當(dāng)命令執(zhí)行完畢后,exit邏輯卻不能再讓shell覆蓋當(dāng)前命令程序了,因?yàn)閟hell從來(lái)就沒(méi)有結(jié)束過(guò),它作為父進(jìn)程只是被交換到了磁盤(pán)而已(后來(lái)內(nèi)存到了,可以容納多個(gè)進(jìn)程時(shí),連交換都不需要了)。

那么exit將讓誰(shuí)來(lái)覆蓋當(dāng)前進(jìn)程呢?

答案是不用覆蓋,按照exit的字面意思,它只要結(jié)束自己就可以了。

本著 自己的資源自己管理的責(zé)任原則 exit只需要清理掉自己分配的資源即可。比如清理掉自己的內(nèi)存空間以及一些其它的數(shù)據(jù)結(jié)構(gòu)。

對(duì)于子進(jìn)程本身而言,由于它是父進(jìn)程生成的,所以它便由父進(jìn)程來(lái)管理釋放。于是經(jīng)典的UNIX進(jìn)程管理四件套正式形成:

到此這篇關(guān)于Unix/Linux fork隱藏的開(kāi)銷的文章就介紹到這了,更多相關(guān)Unix/Linux fork內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!,希望大家以后多多支持腳本之家!

相關(guān)文章

  • Linux域名服務(wù)DNS配置方法

    Linux域名服務(wù)DNS配置方法

    DNS 全稱是 Domain Name System,大意是域名解析系統(tǒng),它的職責(zé)是把域名翻譯成一個(gè)一個(gè)可以識(shí)別的 IP 供不同的計(jì)算機(jī)設(shè)備連接。這篇文章主要介紹了Linux域名服務(wù)DNS配置方法,需要的朋友可以參考下
    2019-08-08
  • Ubuntu16.04環(huán)境下搭建FTP服務(wù)器的教程

    Ubuntu16.04環(huán)境下搭建FTP服務(wù)器的教程

    這篇文章主要介紹了Ubuntu16.04搭建FTP服務(wù)器的教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Ubuntu解決火狐瀏覽器無(wú)法同步書(shū)簽的問(wèn)題【推薦】

    Ubuntu解決火狐瀏覽器無(wú)法同步書(shū)簽的問(wèn)題【推薦】

    最近在ubuntu系統(tǒng)中使用自帶的firefox瀏覽器,發(fā)現(xiàn)有寫(xiě)問(wèn)題,添加書(shū)簽功能無(wú)法使用,下面小編給大家?guī)?lái)了Ubuntu解決火狐瀏覽器無(wú)法同步書(shū)簽的問(wèn)題,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-06-06
  • linux編輯文件保存退出的實(shí)操講解

    linux編輯文件保存退出的實(shí)操講解

    在本篇文章里小編給大家整理的是一篇關(guān)于linux編輯文件保存退出的實(shí)操講解內(nèi)容,需要的朋友們參考下。
    2020-02-02
  • apache虛擬主機(jī)配置一例

    apache虛擬主機(jī)配置一例

    apache虛擬主機(jī)配置一例,有需要的朋友可以參考下
    2013-02-02
  • Apache Rewrite url重定向功能的簡(jiǎn)單配置

    Apache Rewrite url重定向功能的簡(jiǎn)單配置

    Rewrite url重定向就是實(shí)現(xiàn)URL的跳轉(zhuǎn)和隱藏真實(shí)地址,基于Perl語(yǔ)言的正則表達(dá)式規(guī)范。平時(shí)幫助我們實(shí)現(xiàn)擬靜態(tài),擬目錄,域名跳轉(zhuǎn),防止盜鏈等
    2010-08-08
  • linux系統(tǒng)離線安裝nginx全過(guò)程

    linux系統(tǒng)離線安裝nginx全過(guò)程

    這篇文章主要介紹了linux系統(tǒng)離線安裝nginx全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Linux中搭建coturn服務(wù)器的過(guò)程

    Linux中搭建coturn服務(wù)器的過(guò)程

    這篇文章主要介紹了Linux中搭建coturn服務(wù)器,首先下載coturn源碼,進(jìn)入到coturn路徑下執(zhí)行相應(yīng)命令,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Apache配置參數(shù)deny和allow的使用實(shí)例

    Apache配置參數(shù)deny和allow的使用實(shí)例

    這篇文章主要介紹了Apache配置參數(shù)deny和allow的使用實(shí)例,需要的朋友可以參考下
    2015-06-06
  • -bash:/usr/bin/yum:沒(méi)有那個(gè)文件或目錄的解決方案

    -bash:/usr/bin/yum:沒(méi)有那個(gè)文件或目錄的解決方案

    在CentOS系統(tǒng)中,不慎刪除或卸載了yum可以通過(guò)重新安裝來(lái)恢復(fù),首先,確認(rèn)系統(tǒng)版本,例如CentOS,然后新建所需目錄以存放下載的文件,接下來(lái),分別從鏡像源下載yum組件和python依賴的rpm包,安裝python時(shí),如果遇到依賴問(wèn)題,可選擇強(qiáng)制安裝
    2024-10-10

最新評(píng)論