色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

深度剖析Linux中進程控制(上)

jf_78858299 ? 來源:一口Linux ? 作者:土豆居士 ? 2023-05-12 10:49 ? 次閱讀

一、進程創建

fork函數初識

Linux中,fork函數是非常重要的函數,它從已存在進程中創建一個新進程。新進程為子進程,而原進程為父進程。

返回值:

在子進程中返回0,父進程中返回子進程的PID,子進程創建失敗返回-1。

進程調用fork,當控制轉移到內核中的fork代碼后,內核做:

  • 分配新的內存塊和內核數據結構給子進程。
  • 將父進程部分數據結構內容拷貝至子進程。
  • 添加子進程到系統進程列表當中。
  • fork返回,開始調度器調度。

fork之后,父子進程代碼共享。例如:

圖片

運行結果如下:

圖片

這里可以看到,Before只輸出了一次,而After輸出了兩次。其中,Before是由父進程打印的,而調用fork函數之后打印的兩個After,則分別由父進程和子進程兩個進程執行。也就是說,fork之前父進程獨立執行,而fork之后父子兩個執行流分別執行。

注意: fork之后,父進程和子進程誰先執行完全由調度器決定。

fork函數返回值

fork函數為什么要給子進程返回0,給父進程返回子進程的PID?

一個父進程可以創建多個子進程,而一個子進程只能有一個父進程。因此,對于子進程來說,父進程是不需要被標識的;而對于父進程來說,子進程是需要被標識的,因為父進程創建子進程的目的是讓其執行任務的,父進程只有知道了子進程的PID才能很好的對該子進程指派任務。

為什么fork函數有兩個返回值?

父進程調用fork函數后,為了創建子進程,fork函數內部將會進行一系列操作,包括創建子進程的進程控制塊、創建子進程的進程地址空間、創建子進程對應的頁表等等。子進程創建完畢后,操作系統還需要將子進程的進程控制塊添加到系統進程列表當中,此時子進程便創建完畢了。

圖片

也就是說,在fork函數內部執行return語句之前,子進程就已經創建完畢了,那么之后的return語句不僅父進程需要執行,子進程也同樣需要執行,這就是fork函數有兩個返回值的原因。

寫時拷貝

當子進程剛剛被創建時,子進程和父進程的數據和代碼是共享的,即父子進程的代碼和數據通過頁表映射到物理內存的同一塊空間。只有當父進程或子進程需要修改數據時,才將父進程的數據在內存當中拷貝一份,然后再進行修改。

圖片

這種在需要進行數據修改時再進行拷貝的技術,稱為寫時拷貝技術。

1、為什么數據要進行寫時拷貝?

進程具有獨立性。多進程運行,需要獨享各種資源,多進程運行期間互不干擾,不能讓子進程的修改影響到父進程。

2、為什么不在創建子進程的時候就進行數據的拷貝?

子進程不一定會使用父進程的所有數據,并且在子進程不對數據進行寫入的情況下,沒有必要對數據進行拷貝,我們應該按需分配,在需要修改數據的時候再分配(延時分配),這樣可以高效的使用內存空間。

3、代碼會不會進行寫時拷貝?

90%的情況下是不會的,但這并不代表代碼不能進行寫時拷貝,例如在進行進程替換的時候,則需要進行代碼的寫時拷貝。

fork常規用法

  1. 一個進程希望復制自己,使子進程同時執行不同的代碼段。例如父進程等待客戶端請求,生成子進程來處理請求。
  2. 一個進程要執行一個不同的程序。例如子進程從fork返回后,調用exec函數。

fork調用失敗的原因

fork函數創建子進程也可能會失敗,有以下兩種情況:

  1. 系統中有太多的進程,內存空間不足,子進程創建失敗。
  2. 實際用戶的進程數超過了限制,子進程創建失敗。

二、進程終止

進程退出場景

進程退出只有三種情況:

  1. 代碼運行完畢,結果正確。
  2. 代碼運行完畢,結果不正確。
  3. 代碼異常終止(進程崩潰)。

進程退出碼

我們都知道main函數是代碼的入口,但實際上main函數只是用戶級別代碼的入口,main函數也是被其他函數調用的,例如在VS2013當中main函數就是被一個名為__tmainCRTStartup的函數所調用,而__tmainCRTStartup函數又是通過加載器被操作系統所調用的,也就是說main函數是間接性被操作系統所調用的。

既然main函數是間接性被操作系統所調用的,那么當main函數調用結束后就應該給操作系統返回相應的退出信息,而這個所謂的退出信息就是以退出碼的形式作為main函數的返回值返回,我們一般以0表示代碼成功執行完畢,以非0表示代碼執行過程中出現錯誤,這就是為什么我們都在main函數的最后返回0的原因。

當我們的代碼運行起來就變成了進程,當進程結束后main函數的返回值實際上就是該進程的進程退出碼,我們可以使用echo $?命令查看最近一次進程退出的退出碼信息。

例如,對于下面這個簡單的代碼:

圖片

代碼運行結束后,我們可以查看該進程的進程退出碼。

[cl@VM-0-15-centos procTermination]$ echo $?

圖片

這時便可以確定main函數是順利執行完畢了。

為什么以0表示代碼執行成功,以非0表示代碼執行錯誤?

因為代碼執行成功只有一種情況,成功了就是成功了,而代碼執行錯誤卻有多種原因,例如內存空間不足、非法訪問以及棧溢出等等,我們就可以用這些非0的數字分別表示代碼執行錯誤的原因。

C語言當中的strerror函數可以通過錯誤碼,獲取該錯誤碼在C語言當中對應的錯誤信息:

圖片

運行代碼后我們就可以看到各個錯誤碼所對應的錯誤信息:

圖片

實際上Linux中的ls、pwd等命令都是可執行程序,使用這些命令后我們也可以查看其對應的退出碼。

可以看到,這些命令成功執行后,其退出碼也是0。

圖片

但是命令執行錯誤后,其退出碼就是非0的數字,該數字具體代表某一錯誤信息。

圖片

注意: 退出碼都有對應的字符串含義,幫助用戶確認執行失敗的原因,而這些退出碼具體代表什么含義是人為規定的,不同環境下相同的退出碼的字符串含義可能不同。

進程正常退出

return退出

在main函數中使用return退出進程是我們常用的方法。

例如,在main函數最后使用return退出進程。

圖片

運行結果:

圖片

exit函數

使用exit函數退出進程也是我們常用的方法,exit函數可以在代碼中的任何地方退出進程,并且exit函數在退出進程前會做一系列工作:

  1. 執行用戶通過atexit或on_exit定義的清理函數。
  2. 關閉所有打開的流,所有的緩存數據均被寫入。
  3. 調用_exit函數終止進程。

例如,以下代碼中exit終止進程前會將緩沖區當中的數據輸出。

圖片

運行結果:

圖片

_exit函數

使用_exit函數退出進程的方法我們并不經常使用,_exit函數也可以在代碼中的任何地方退出進程,但是_exit函數會直接終止進程,并不會在退出進程前會做任何收尾工作。

例如,以下代碼中使用_exit終止進程,則緩沖區當中的數據將不會被輸出。

圖片

運行結果:

圖片

return、exit和_exit之間的區別與聯系

return、exit和_exit之間的區別

只有在main函數當中的return才能起到退出進程的作用,子函數當中return不能退出進程,而exit函數和_exit函數在代碼中的任何地方使用都可以起到退出進程的作用。

使用exit函數退出進程前,exit函數會執行用戶定義的清理函數、沖刷緩沖,關閉流等操作,然后再終止進程,而_exit函數會直接終止進程,不會做任何收尾工作。

圖片

return、exit和_exit之間的聯系

執行return num等同于執行exit(num),因為調用main函數運行結束后,會將main函數的返回值當做exit的參數來調用exit函數。

圖片

使用exit函數退出進程前,exit函數會先執行用戶定義的清理函數、沖刷緩沖,關閉流等操作,然后再調用_exit函數終止進程。

進程異常退出

情況一:向進程發生信號導致進程異常退出。

例如,在進程運行過程中向進程發生kill -9信號使得進程異常退出,或是使用Ctrl+C使得進程異常退出等。

情況二:代碼錯誤導致進程運行時異常退出。

例如,代碼當中存在野指針問題使得進程運行時異常退出,或是出現除0的情況使得進程運行時異常退出等。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11292

    瀏覽量

    209333
  • PID
    PID
    +關注

    關注

    35

    文章

    1472

    瀏覽量

    85480
  • 函數
    +關注

    關注

    3

    文章

    4327

    瀏覽量

    62573
  • 數據結構
    +關注

    關注

    3

    文章

    573

    瀏覽量

    40123
  • Fork
    +關注

    關注

    0

    文章

    14

    瀏覽量

    3294
收藏 人收藏

    評論

    相關推薦

    Linux中進程和線程的深度對比

    關于進程和線程,在 Linux 中是一對兒很核心的概念。但是進程和線程到底有啥聯系,又有啥區別,很多人還都沒有搞清楚。
    發表于 10-14 16:47 ?1304次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>中進程</b>和線程的<b class='flag-5'>深度</b>對比

    Linux進程是如何創建出來的?

    Linux 中,進程是我們非常熟悉的東東了,哪怕是只寫過一天代碼的人也都用過它。但是你確定它不是你最熟悉的陌生人?我們今天通過深度剖析進程
    發表于 11-15 09:27 ?576次閱讀

    linux內核深度剖析,另附有光盤資料

    linux內核深度剖析,對于想學linux內核的人來說,絕對值得一看,另附有光盤資料。
    發表于 01-15 21:25

    C語言深度剖析

    C語言深度剖析[完整版].pdfC語言深度剖析[完整版].pdf (919.58 KB )
    發表于 03-19 05:11

    Linux系統中進程如何查看及控制

    Linux系統中進程的查看及控制
    發表于 06-09 08:34

    Linux系統中的進程控制該怎樣去實現呢

    Linux系統編程、網絡編程》第5章 進程控制 2008年畢業于沈陽航空航...
    發表于 12-23 07:55

    Linux源碼分析系列的進程

    概述:相關概念,進程在整個內核中的功能位置,源代碼中進程相關的文件源代碼中進程相關的文件。 Linux核心是多任務的,運行的程序稱作進程 (
    發表于 11-03 22:26 ?32次下載

    Linux進程控制編程

    7.2 Linux進程控制編程 1.fork() 在Linux中創建一個新進程的惟一方法是使用fork()函數。fork()函數是Linux
    發表于 10-18 14:16 ?0次下載

    Linux守護進程詳解

    分享到:標簽:進程控制 Linux 守護進程進程 7.3 Linux守護進程 7.3.1 守
    發表于 10-18 14:24 ?0次下載
    <b class='flag-5'>Linux</b>守護<b class='flag-5'>進程</b>詳解

    uClinux進程調度器的實現分析

    uClinux中進程調度器的實現原理,展示了uClinux中獨具特色的進程調度機制。 關鍵詞:uClinux;調度策略;進程調度器 0. 引言 uClinux是針對控制領域的嵌入式
    發表于 11-06 14:30 ?0次下載

    基于Linux進程管理的詳細剖析

    一篇,我們講到了Linux內核開發和應用程序開發,今天我們來講講Linux重點部分Linux進程管理。
    的頭像 發表于 01-26 11:24 ?3733次閱讀
    基于<b class='flag-5'>Linux</b><b class='flag-5'>進程</b>管理的詳細<b class='flag-5'>剖析</b>

    Linux和UNIX可以用什么命令查看運行中進程的相關信息

      你可以使用ps命令。它能顯示當前運行中進程的相關信息,包括進程的PID。Linux和UNIX都支持ps命令,顯示所有運行中進程的相關信息。ps命令能提供一份當前
    發表于 01-20 09:42 ?6461次閱讀

    Linux0.11-進程控制塊數據結構

    嵌入式Linux中文站收集整理Linux0.11版本內核學習筆記,本文分析了Linux進程控制模塊的數據結構。
    發表于 05-15 15:22 ?972次閱讀

    深度剖析Linux中進程控制(下)

    Linux中,fork函數是非常重要的函數,它從已存在進程中創建一個新進程。新進程為子進程,而原進程
    的頭像 發表于 05-12 10:49 ?497次閱讀
    <b class='flag-5'>深度</b><b class='flag-5'>剖析</b><b class='flag-5'>Linux</b><b class='flag-5'>中進程控制</b>(下)

    Linux中進程、線程和協程的基礎概念

    進程是計算機中運行的程序的實例,它是操作系統中最基本的執行單元之一。每個進程都有自己的獨立內存空間、系統資源和代碼執行流。這意味著一個進程的崩潰通常不會影響其他進程
    的頭像 發表于 12-06 09:22 ?851次閱讀
    主站蜘蛛池模板: 99亚洲精品自拍AV成人软件| jizzjizz中国大学生| CHINSEFUCKGAY无套| 国产精品爽爽久久久久久竹菊| 樱花动漫成人隐藏入口| YELLOW视频在线观看最新| 韩国成人理伦片免费播放| 男人一进一出桶女人视频| 午夜福利体检| 在线观看成人免费| 国产 亚洲 中文在线 字幕| 久久精品国产欧美成人| 肉肉的各种姿势高H细文| 在线国产视频观看| 国产成年人在线观看| 美女脱三角裤| 晓雪老师我要进你里面好爽| 99精彩免费观看| 黄色片软件大全| 人妻天天爽夜夜爽三区麻豆A片| 女人高潮时一吸一夹| 小货SAO边洗澡边CAO你动漫| 97免费观看视频| 韩国无遮羞禁动漫在线观看96| 黄色直接观看| 日本伦子欲| 中文字幕在线久热精品| 国产精品色无码AV在线观看| 美女18黄| 亚洲午夜精品AV无码少妇| 操老太太的逼| 理论片午午伦夜理片影院| 亚洲国产在线2020最新| 东北女人一级毛片| 嫩草国产福利视频一区二区| 亚洲人成77777在线视频| 高h乱np甄宓| 欧美日韩另类在线观看视频| 伊人伊人影院| 和老外3p爽粗大免费视频| 色婷婷五月综合久久中文字幕|