Linux進(jìn)和創(chuàng)建——寫時拷貝機(jī)制

      網(wǎng)友投稿 760 2025-03-31

      所有的進(jìn)程都是PID為1的init進(jìn)程的后代。內(nèi)核在系統(tǒng)啟動的最后階段啟動init進(jìn)程。該進(jìn)程會讀取系統(tǒng)的初始化腳本(initscript)并執(zhí)行其他相關(guān)的程序,最終完成整個系統(tǒng)的啟動過程。

      內(nèi)核把進(jìn)程(在linux中進(jìn)程又稱任務(wù))存放在任務(wù)隊列中。任務(wù)隊列是雙向循環(huán)鏈表。鏈表中的每一項數(shù)據(jù)的類型都是task_struct,task_struct就是所謂的進(jìn)程描述符的結(jié)構(gòu)。進(jìn)程描述符中包含一個進(jìn)程的所有信息。進(jìn)程描述符所包含的數(shù)據(jù)能完整地描述一個正在執(zhí)行的程序(程序本身并不是進(jìn)程,進(jìn)程是處于執(zhí)行期的程序以及相關(guān)的資源的總稱)如它打開的文件,進(jìn)程的地址空間,掛起的信號,進(jìn)程的狀態(tài)等等。

      可執(zhí)行程序代碼是進(jìn)程的重要組成部分。這些代碼從一個可執(zhí)行文件載入到進(jìn)程的地址空間執(zhí)行。一般程序在用戶空間執(zhí)行。當(dāng)一個程序執(zhí)行了系統(tǒng)調(diào)用或者觸發(fā)了某個異常,它就會陷入內(nèi)核空間,此時,內(nèi)核“代表進(jìn)程執(zhí)行”并處于進(jìn)程上下文中。在此期間除非有更高優(yōu)先級的進(jìn)程需要執(zhí)行并由調(diào)度器做出了相應(yīng)調(diào)整,否則在內(nèi)核退出時,程序恢復(fù),在用戶空間會繼續(xù)執(zhí)行。系統(tǒng)調(diào)用和異常處理程序是對內(nèi)核明確定義的接口,進(jìn)程只有通過這些接口才能陷入內(nèi)核執(zhí)行。對內(nèi)核的所有訪問都必須通過這些接口。

      系統(tǒng)中的每個進(jìn)程必有一個父進(jìn)程,相應(yīng)的,每個進(jìn)程也可以擁有零個或多個子進(jìn)程。擁有同一個父進(jìn)程的所有進(jìn)程稱為兄弟。進(jìn)程間的關(guān)系存放在進(jìn)程描述符中。每個task_struct(進(jìn)程描述符結(jié)構(gòu))都包含一個指向其父進(jìn)程task_struct的名為parent的指針,還包含一個稱為children的子進(jìn)程鏈表。

      init進(jìn)程的進(jìn)程描述符是作為init_task靜態(tài)分配的。

      許多操作系統(tǒng)在創(chuàng)建新進(jìn)程時,都會首先在新的地址空間里創(chuàng)建進(jìn)程,讀入可執(zhí)行文件,最后開始執(zhí)行。而linux則不是,它將這兩個步驟分解到兩個單獨(dú)的函數(shù)中去執(zhí)行:fork()和exec(),首先fork()通過拷貝當(dāng)前進(jìn)程創(chuàng)建一個子進(jìn)程,子進(jìn)程與父進(jìn)程的區(qū)別僅僅在于PID(每個進(jìn)程唯一),PPID(父進(jìn)程的進(jìn)程號,子進(jìn)程將其設(shè)置為被拷貝進(jìn)程的PID),和某些資源和統(tǒng)計量。exec()函數(shù)負(fù)責(zé)讀取可執(zhí)行文件并將其載入地址空間開始運(yùn)行。

      創(chuàng)建子進(jìn)程是通過fork()方法完成的,而fork()是使用寫時拷貝(copy-on-write)機(jī)制。這是一種可以推遲甚至免除拷貝數(shù)據(jù)的技術(shù)。當(dāng)執(zhí)行fork()方法創(chuàng)建進(jìn)程時,內(nèi)核并不復(fù)制整個進(jìn)程地址空間,而是讓父進(jìn)程和子進(jìn)程共享同一個拷貝。

      只有在需要寫入的時候,數(shù)據(jù)才會被復(fù)制,從而使各個進(jìn)程擁有各自的拷貝。即是說,資源的復(fù)制只有在需要寫入時才進(jìn)行,在此之前,都是以只讀方式共享。

      如果fork()之后立即調(diào)用exec()那么頁就根據(jù)無須復(fù)制了,這種情況下,頁根本不會被寫入。

      fork()的實際開銷就是復(fù)制父進(jìn)程的頁表和給子進(jìn)程創(chuàng)建唯一的進(jìn)程描述符。

      Linux通過clone()系統(tǒng)調(diào)用實現(xiàn)fork()。clone系統(tǒng)調(diào)用會通過一系列的參數(shù)標(biāo)志來指明父、子進(jìn)程需要共享的資源。clone()會去調(diào)用do_fork()。

      do_fork會完成創(chuàng)建中的大部分工作,它會調(diào)用copy_process()函數(shù),然后讓進(jìn)程開始運(yùn)行。copy_process()函數(shù)完成以下工作:

      (1)首先調(diào)用dup_task_struct為新進(jìn)程創(chuàng)建一個內(nèi)核棧、thread_info結(jié)構(gòu)和task_struct(進(jìn)程描述符的結(jié)構(gòu)),這些值與當(dāng)前進(jìn)程的值相同。此時的子進(jìn)程與父進(jìn)程的描述符是完全相同的。

      (2)檢查并確保新創(chuàng)建這個子進(jìn)程后,當(dāng)前用戶所擁有的進(jìn)程數(shù)目沒有超出給它分配的資源的限制。

      (3)子進(jìn)程開始著手使自己與父進(jìn)程區(qū)別開來。子進(jìn)程描述符內(nèi)的許多成員都被清0或設(shè)為初始值。那些不是繼承而來的描述符成員,主要是統(tǒng)計信息。此時task_struct中仍然有很多數(shù)據(jù)都依然未被修改。

      (4)將子進(jìn)程的狀態(tài)設(shè)置為TASK_UNINTERRUPTIBLE以保證它不會投入運(yùn)行。

      (5)copy_process()調(diào)用copy_flags()以更新task_struct的flags 成員,表明進(jìn)程是否有超級用戶權(quán)限的PF_SUPERPRIV標(biāo)志被清0,表明進(jìn)程沒有調(diào)用exec()函數(shù)的PF_FORKNOEXEC標(biāo)志被設(shè)置。

      (6)調(diào)用alloc_pid為新進(jìn)程分配一個有效的PID。

      Linux進(jìn)和創(chuàng)建——寫時拷貝機(jī)制

      (7)根據(jù)傳遞給clone()的參數(shù)標(biāo)志,copy_process()拷貝或共享打開的文件、文件系統(tǒng)信息、信號處理函數(shù)、進(jìn)程地址空間和命名空間等。在一般情況下,這些資源會被給定進(jìn)程的所有線程共享;否則這些資源對每個進(jìn)程是不同的,因此被拷貝到這里。

      (8)最后,copy_process()做收尾工作并返回一個指向子進(jìn)程的指針。再回到do_fork()函數(shù),如果copy_process()函數(shù)成功返回,新創(chuàng)建的子進(jìn)程會被喚醒并讓其投入運(yùn)行。

      一般子進(jìn)程都會馬上調(diào)用exec()函數(shù),這樣可以避免寫時拷貝的額外開銷。

      謝謝閱讀。

      Linux 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Word2103文檔中輸入任意帶圈數(shù)字的技巧(在word中怎樣輸入帶圈的數(shù)字)
      下一篇:excel表格中如何把相同的放一起(怎么把excel表格一樣的放在一起)
      相關(guān)文章
      91情国产l精品国产亚洲区 | 亚洲成aⅴ人在线观看| 最新国产AV无码专区亚洲 | 国产成人亚洲综合无| 亚洲乱理伦片在线观看中字 | 中国亚洲女人69内射少妇| 亚洲色一色噜一噜噜噜| 亚洲国产成人精品无码久久久久久综合 | 亚洲国产精品国自产电影| 久热综合在线亚洲精品| 国产V亚洲V天堂A无码| 亚洲精品tv久久久久久久久| 亚洲欧洲美洲无码精品VA | 亚洲伦理中文字幕| 久久亚洲最大成人网4438| 99999久久久久久亚洲| 亚洲午夜无码久久| 精品亚洲av无码一区二区柚蜜| 最新亚洲人成无码网www电影| 国产亚洲视频在线观看| 国产亚洲蜜芽精品久久| 亚洲成年人啊啊aa在线观看| 国产亚洲精品国看不卡| 亚洲精品无码永久在线观看你懂的 | 久久亚洲精品无码VA大香大香| 亚洲视频免费观看| 亚洲AV无码乱码在线观看代蜜桃 | 亚洲变态另类一区二区三区| 婷婷亚洲综合一区二区| 亚洲国产精品自在拍在线播放| 亚洲片一区二区三区| 亚洲日韩中文无码久久| 亚洲第一成年男人的天堂| 亚洲小视频在线播放| 亚洲欧美综合精品成人导航| 精品久久久久亚洲| 亚洲中文字幕久久精品无码喷水| 久久精品国产精品亚洲色婷婷| 亚洲熟妇无码爱v在线观看| 亚洲人成77777在线观看网| 相泽南亚洲一区二区在线播放|