Linux——進程終止/等待/替換

前言

? 本章主要對進程終止,進程等待,進程替換的詳細認識,根據實驗去理解其中的原理,干貨滿滿!

1.進程終止

概念:進程終止就是釋放進程申請的內核數據結構和對應的代碼和數據

進程退出的三種狀態

  • 代碼運行完畢 結果正確??
  • 代碼運行完畢 結果錯誤
  • 代碼中止異常

我們在學習C語言的時候,寫main函數,一般都會寫return 0;main函數的返回值,通常就代表程序的執行情況,0代表成功,非0代表代碼運行完畢,結果錯誤,不同的值代表不同的錯誤

當父進程創建子進程是為了讓子進程完成某種任務,當子進程結束,肯定要將執行結果返回給父進程,讓父進程知道是什么情況,我們知道子進程結束會保留task_struct,等待父進程獲取結果信息,此時子進程就是僵尸進程,執行結果,也就是返回值就會存放到task_struct中,被父進程獲取

1.1退出碼

進程結束返回的一個狀態 通常是一個整數值?

echo $?

打印最近一個進程退出時的退出碼

errno:當庫函數調用失敗或者系統調用失敗 他們通常會將一個特定的錯誤代碼賦值給errno

?strerror是C語言的一個庫函數,該函數接收一個errno的錯誤代碼作為參數, strerror負責將這些錯誤代碼轉換為具體的錯誤描述信息,一共有134條

我們可以看到0表示成功? 1表示操作不被允許? 2表示沒有這個目錄或文件 3表示沒有這個進程

相信后面的大家也可以讀懂? 這樣我們就可以根據退出碼知道我們的錯誤是什么了

?

此時在當前目錄并沒有c.txt文件,ls是C語言寫的一個程序,當執行完程序,發現文件不存在,此時的退出碼是2,不就是上面的2號找不到文件嗎?

1.2進程常見的退出方法

1.2.1從main返回

我們知道main函數是程序的入口,當main函數結束,也return了,進程也就結束了

其他的函數只表示調用函數完成了 返回退出碼 并不代碼進程結束

1.2.2exit

exit手冊內容? ?exit是直接結束進程,引起進程終止? 它需要一個參數,就是狀態(進程退出碼)

1.2.3_exit?

_exit手冊內容? 用于終止進程的系統調用? 通過實驗我們發現和exit一樣都可以終止進程

?1.2.4exit和_exit區別

補充:我們知道只有OS才可以殺掉進程 庫和系統調用是上下層的關系 庫調用系統調用

相同點:都可以終止進程

不同點:

  • exit是標準C庫函數 _exit是系統調用
  • exit會刷新緩沖區 _exit不會刷新緩沖區

實驗:通過下面的實驗我們也可以驗證exit不會刷新緩沖區

2.進程等待

在理解進程等待前,我們先來想一下進程為什么要進行等待呢?

  • 回收子進程資源(處理僵尸進程)
  • 獲取子進程退出信息

我們知道當子進程退出時,task_struct不會被釋放,需要父進程回收資源,當父進程一直不管時,就可能會造成僵尸進程,可能會出現內存泄露

2.1wait?

手冊內容:wait的參數status是一個輸出型參數 在后續的waitpid我們會詳細了解

wait會等待任意一個子進程 回收成功會返回回收的pid

接下來我們來使用一下wait?

創建一個子進程 讓他跑五次 當子進程結束時,讓程序暫停10s,這個時候父進程還沒有回收資源,所以子進程此時就是僵尸進程,根據子進程狀態我們可以看到是Z,父進程回收子進程資源,解決了僵尸進程,返回了子進程的pid,子進程資源被全部釋放,剩余父進程,程序再休眠10s,最后父進程進程也結束

?2.2waitpid

pid_t waitpid(pid_t pid, int *status, int options);? waitpid共有三個參數

接下來會一個一個拆開分析:

?2.2.1pid_t pid

pid_id的值有四種

等待指定pid或者等待任意子進程?

?如果等待失敗 會出現什么樣的情況呢?

2.2.2int *status

輸出型參數 存儲進程退出時的狀態信息 不關心狀態信息設置NULL

我們來進行測試一下:發現出現了一些問題

status不能當做整型看待,可以當做位圖來看待,前16位不考慮,次8位是退出狀態,那么此時應該前7位是0,然后是1,后面還有8個0,因為是2進制,所以應該是2的8次方,也就是256!

當除數為0時就會使程序出現異常

????????其實exit code 和 exit signal都存放在子進程的task_struct中,當子進程是僵尸進程,等待父進程通過操作系統調用回收子進程資源,獲取子進程的退出信息

????????我們在上述的實驗是通過位操作來提取信息的,真正的OS是使用宏,其實就是封裝了一下位操作

  • WIFEXITED(status): 若為正常終止子進程返回的狀態,則為真。(查看進程是
否是正常退出,程序是否異常,=0為真)
  • WEXITSTATUS(status): WIFEXITED非零,提取子進程退出碼。(查看進程的
退出碼)

2.2.3int options?

補充:

  • 阻塞調用:當一個程序發起操作時,程序會暫停操作,直到這個操作完成并返回結果,在執行操作時,程序不能做任何事,也就是子進程在執行任務時,父進程一直在wait阻塞
  • 非阻塞調用:當一個程序發起操作,不會等操作完成,而是立即返回,執行后續的操作,程序可以定期檢查這個操作是否已經完成,這個操作叫做非阻塞輪詢

我們從手冊里可以看到options是有幾個選項的

  • 默認是0:阻塞調用,如果子進程還沒有退出父進程就會一直阻塞在那里
  • WNOHANG:非阻塞調用

waitpid的返回值可以是 -1? 0? >0

-1表示失敗

0表示 調用結束 但是子進程沒有退出

>0 子進程結束

非阻塞輪詢實驗,將waitpid的第三個參數設置為WNOHANG,非阻塞調用,這樣父進程就不會一直等待子進程完成任務,而是立即返回,然后定期去詢問子進程完成任務了嗎?

非阻塞調用實驗:我們可以通過函數指針回調函數來操作

通過實驗我們可以看到在子進程執行任務時,父進程也在執行其他任務

3.進程替換 exec

進程替換就是OS根據指定的程序文件路徑和參數,將新程序的代碼和數據加載到當前進程的地址空間中,覆蓋原來的進程內容,從而實現進程替換

程序替換錯誤返回-1 沒有成功返回值?

當我們知道程序替換會將原先的程序進行覆蓋,我們原先的程序就沒有了,所以我們一般會創建子進程去執行程序替換,這樣父進程的代碼數據也不會丟失了!!?

3.1進程替換的原理

我們先來使用一下execl,我們可以發現第一句printf執行了,然后執行程序替換,然后就沒有輸出了,我們來了解一下程序替換的原理!其實在上面就已近談到了,就是將新程序的代碼和數據加載到當前進程的地址空間中,覆蓋替換原來的進程內容,從而實現進程替換

在程序替換的過程中,并沒有創建新的進程

3.2程序替換接口函數

我們在上面的手冊中可以看到6個接口函數,接下來我們學習四個 后續的大家肯定就都懂

還有一個是系統命令 execve? 我們在上面看到的6個接口函數其實都是需要去調用execve

在上層進行封裝 為了應對各種各樣的場景 最后會統一轉化 調用系統調用execve

3.2.1execl

int execl(const char *path, const char *arg, ...);

execl的l可以看做是一個list,第一個參數就是路徑+程序名,第二個參數就是命令,在命令行怎么寫,這里我們就怎么寫,...是可變參數列表的意思,因為我們不知道命令有幾個,最后要以NULL結尾,表明參數已傳完!!

?3.2.2 execlp

int execlp(const char *file, const char *arg, ...);

?execlp的l看做list,p看做PATH,第一個參數就是要執行的文件名,execp會自動在環境變量PATH中查找命令,第二個參數就是命令,同上!

3.2.3execv?

int execv(const char *path, char *const argv[]);

execv的v可以看做是一個vector,第一個參數是要執行的路徑+文件名,第二個參數是一個指針數組,也就是命令行參數表?

3.2.4execvp

int execvp(const char *file, char *const argv[]);

execvp的v可以理解為vector,p理解為PATH,第一個參數就是要執行的文件,第二個是指針數組,就是指命令行參數表,相信大家看到這里一看就看懂了!!

3.2.5??execvpe

int execvpe(const char *file, char *const argv[], char *const envp[]);

execvpe的v可以看做vector,e看做environment,第一個參數就是要執行的文件,第二個就是命令行參數表,第三個也是一個指針數組,是環境變量表,這里的環境變量表會進行覆蓋替換父進程的環境變量表,當然也有方法在原始的環境變量表的基礎上進行添加!!

補充?

putenv 添加環境變量的參數

envrion 訪問當前環境的整個環境列表

解決方案 :

  • 不使用需要傳帶env的參數 直接進行putenv
  • 使用傳env的參數 putenv? envrion

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78722.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

iOS開發架構——MVC、MVP和MVVM對比

文章目錄 前言MVC(Model - View - Controller)MVP(Model - View - Presenter)MVVM(Model - View - ViewModel) 前言 在 iOS 開發中,MVC、MVVM、和 MVP 是常見的三種架構模式,它們主…

0506--01-DA

36. 單選題 在娛樂方式多元化的今天,“ ”是不少人(特別是中青年群體)對待戲曲的態度。這里面固然存在 的偏見、難以靜下心來欣賞戲曲之美等因素,卻也有另一個無法回避的原因:一些戲曲雖然與觀眾…

關于Java多態簡單講解

面向對象程序設計有三大特征,分別是封裝,繼承和多態。 這三大特性相輔相成,可以使程序員更容易用編程語言描述現實對象。 其中多態 多態是方法的多態,是通過子類通過對父類的重寫,實現不同子類對同一方法有不同的實現…

【Trea】Trea國際版|海外版下載

Trea目前有兩個版本,海外版和國內版。? Trae 版本差異 ?大模型選擇?: ?國內版?:提供了字節自己的Doubao-1.5-pro以及DeepSeek的V3版本和R1版本。海外版:提供了ChartGPT以及Claude-3.5-Sonnet和3.7-Sonnt. ?功能和界面?&a…

Missashe考研日記-day33

Missashe考研日記-day33 1 專業課408 學習時間:2h30min學習內容: 今天開始學習OS最后一章I/O管理的內容,聽了第一小節的內容,然后把課后習題也做了。知識點回顧: 1.I/O設備分類:按信息交換單位、按設備傳…

鏈表的面試題3找出中間節點

來來來,接著繼續我們的第三道題 。 解法 暴力求解 快慢指針 https://leetcode.cn/problems/middle-of-the-linked-list/submissions/ 這道題的話,思路是非常明確的,就是讓你找出我們這個所謂的中間節點并且輸出。 那這道題我們就需要注意…

linux磁盤介紹與LVM管理

一、磁盤基本概述 GPT是全局唯一標識分區表的縮寫,是全局唯一標示磁盤分區表格式。而MBR則是另一種磁盤分區形式,它是主引導記錄的縮寫。相比之下,MBR比GPT出現得要更早一些。 MBR 與 GPT MBR 支持的磁盤最大容量為 2 TB,GPT 最大支持的磁盤容量為 18 EB,當前數據盤支持…

突破測試環境文件上傳帶寬瓶頸!React Native 阿里云 OSS 直傳文件格式問題攻克二

上一篇我們對服務端和阿里云oss的配置及前端調用做了簡單的介紹,但是一直報錯。最終判斷是文件格式問題,通常我們在reactnative中用formData上傳, formData.append(file, {uri: file, name: nameType(type), type: multipart/form-data});這…

Spring Boot 中 @Bean 注解詳解:從入門到實踐

在 Spring Boot 開發中,Bean注解是一個非常重要且常用的注解,它能夠幫助開發者輕松地將 Java 對象納入 Spring 容器的管理之下,實現對象的依賴注入和生命周期管理。對于新手來說,理解并掌握Bean注解,是深入學習 Spring…

TCP 協議設計入門:自定義消息格式與粘包解決方案

目錄 一、為什么需要自定義 TCP 協議? TCP粘包問題的本質 1.1 粘包與拆包的定義 1.2 粘包的根本原因 1.3 粘包的典型場景 二、自定義消息格式設計 2.1 協議結構設計 方案1:固定長度協議 方案2:分隔符標記法 方案3:長度前…

了解一下OceanBase中的表分區

OceanBase 是一個高性能的分布式關系型數據庫,它支持 SQL 標準的大部分功能,包括分區表。分區表可以幫助管理大量數據,提高查詢效率,通過將數據分散到不同的物理段中,可以減少查詢時的數據掃描量。 在 OceanBase 中操…

多線程網絡編程:粘包問題、多線程/多進程服務器實戰與常見問題解析

多線程網絡編程:粘包問題、多線程/多進程服務器實戰與常見問題解析 一、TCP粘包問題:成因、影響與解決方案 1. 粘包問題本質 TCP是面向流的協議,數據傳輸時沒有明確的消息邊界,導致多個消息可能被合并(粘包&#xf…

大模型主干

1.什么是語言模型骨架LLM-Backbone,在多模態模型中的作用? 語言模型骨架(LLM Backbone)是多模態模型中的核心組件之一。它利用預訓練的語言模型(如Flan-T5、ChatGLM、UL2等)來處理各種模態的特征,進行語義…

[創業之路-350]:光刻機、激光器、自動駕駛、具身智能:跨學科技術體系全景解析(光-機-電-材-熱-信-控-軟-網-算-智)

光刻機、激光器、自動駕駛、具身智能四大領域的技術突破均依賴光、機、電、材、熱、信、控、軟、網、算、智十一大學科體系的深度耦合。以下從技術原理、跨學科融合、關鍵挑戰三個維度展開系統性分析: 一、光刻機:精密制造的極限挑戰 1. 核心技術與學科…

SVTAV1 編碼函數 svt_aom_is_pic_skipped

一 函數解釋 1.1 svt_aom_is_pic_skipped函數的作用是判斷當前圖片是否可以跳過編碼處理。 具體分析如下 函數邏輯 參數說明:函數接收一個指向圖片父控制集的指針PictureParentControlSet *pcs, 通過這個指針可以獲取與圖片相關的各種信息,用于判斷是否跳…

【Redis新手入門指南】從小白入門到日常使用(全)

文章目錄 前言redis是什么?定義原理與特點與MySQL對比 Redis安裝方式一、Homebrew 快速安裝 Redis(推薦)方式二、源碼編譯安裝redisHomebrew vs 源碼安裝對比 redis配置說明修改redis配置的方法常見redis配置項說明 redis常用命令redis服務啟…

Linux grep 命令詳解及示例大全

文章目錄 一、基本語法二、常用選項及示例1. 基本匹配:查找包含某字符串的行2. 忽略大小寫匹配 -i3. 顯示行號 -n4. 遞歸查找目錄下的文件 -r 或 -R5. 僅顯示匹配的字符串 -o6. 使用正則表達式 -E(擴展)或 egrep7. 顯示匹配前后行 -A, -B, -C…

【排序算法】快速排序(全坤式超詳解)———有這一篇就夠啦

【排序算法】——快速排序 目錄 一:快速排序——思想 二:快速排序——分析 三:快速排序——動態演示圖 四:快速排序——單趟排序 4.1:霍爾法 4.2:挖坑法 4.3:前后指針法 五:…

【platform push 提示 Invalid source ref: HEAD】

platform push 提示 Invalid source ref: HEAD 場景:環境:排查過程:解決: 場景: 使用platform push 命令行輸入git -v 可以輸出git 版本號,但就是提示Invalid source ref: HEAD,platform creat…

x-cmd install | Tuistash - Logstash 實時監控,告別圖形界面,高效便捷!

目錄 核心優勢,一覽無遺安裝適用場景,廣泛覆蓋功能亮點,不容錯過 還在為 Logstash 的監控而頭疼嗎?還在頻繁切換圖形界面查看數據嗎?現在,有了 Tuistash,一切都將變得簡單高效! Tui…