【Linux】進程終止與進程等待

目錄

進程終止

errno

exit和_exit

進程等待

wait和waitpid

宏:WIFEXITED

非阻塞等待


進程終止

下面要談的一個話題就是進程終止,就是說一個進程退出了,可能有三種情況

1.進程代碼執行完,結果是正確的

2.進程代碼執行完,結果是錯誤的

3.進程代碼沒有執行完,進程出異常了,中途退出了

其實我們寫的main函數執行起來就是一個進程,而我們一般寫的return 0,就叫做進程的退出碼。一般0表示正確執行,第一種情況;而非0表示執行失敗,第二種情況。因為main函數的return 0就已經是代碼的最后部分了。

為什么用非0表示執行失敗呢?因為成功就是成功了,而失敗可能會有很多種原因。進程的退出碼是給機器看的,要是給人看,就要把退出碼轉化成錯誤描述,這個錯誤描述可以是系統或語言自帶的,也可以自定義,下面我們先用strerror函數看一下系統中的錯誤描述

我們可以看到有很多錯誤描述,到133個了

這時我們就能解釋我們瞎給比如ls 后面一個選項,bash進程,就是命令行解釋器報的錯是什么了,比如:

這不就是上面的二號錯誤嗎,另外,下面的指令可以查看最近一次進程的退出碼

為什么第二次用顯示0呢?因為echo $?也是一個進程它是成功執行的

我們上面說也可以自定義,那就可以創建幾個字符串枚舉值,并且枚舉值是可以表示整數的,這樣就可以自己去定義錯誤碼了,比如:

上面我們說了前兩種情況,第三種情況是進程沒有執行完,中途出現異常了,只要中間出現異常,其實結果對與否就沒有意義了。其實中途出現異常本質上就是進程收到了異常信號,就是kill -l那一系列的信號

比如:

8號信號對應的是?SIGFPE(Floating-Point Exception)信號。這個信號用于指示浮點運算異常,比如除以零或溢出等情況。

11號信號對應的是?SIGSEGV(Segmentation Fault)信號。這個信號用于指示進程發生了內存段錯誤,即試圖訪問無效的內存地址。

并且有一個細節就是這些錯誤是從1開始的,這跟我們下面的如何用16比特位表示退出碼和收到什么信號是有關系的,并且這些大寫的字母都是宏定義

所以進程執行的情況可以由兩個數字表示,一個是收到什么信號(0就表示沒有收到信號),一個是退出碼。

errno

除了進程退出,就是main函數退出,我們還有普通函數退出,那我們如何知道它的運行情況呢?我們也有個存放錯誤碼的東西,叫errno,就是說,函數如果執行失敗的話,那么錯誤碼會放在erron這個整形變量里,這個一般庫函數才會有這個錯誤碼,因為庫函數內部一般是有這個賦值的,我們一般寫的函數沒有,比如fopen,可以看一下它的返回值

可以看到errno這個東西,下面寫一個代碼看一下

其實我當前目錄根本就沒有這個文件,并且是以只讀的方式打開文件,所以它肯定會出錯,錯誤信息就存在errno里面,我們也可以看具體字符信息,運行之后就是這樣

exit和_exit

我們如果想讓一個進程退出可以用exit或_exit前者是庫函數,后者是系統調用,我們可以來查一下

這里的參數status就是你想讓進程退出時的退出碼,我們通過一段代碼來展示一下它們的區別

我們寫這樣一個代碼,運行完后發現什么都不打印,而把_exit改成exit后就會打印,這就說明exit會刷新緩沖區其實exit就是封裝了_exit,為什么要這樣做呢?

其實我們知道庫函數和系統調用是上下層關系,不同的操作系統的系統調用是不同的,比如Windows下_exit就用不了,所以這時我們把系統調用再封裝一層成為庫函數,不同的操作系統封裝不同的系統調用,但是它們的庫函數的接口就是一樣的了,這就通過庫函數屏蔽掉了系統調用的差異,就實現了語言的可移植性和跨平臺性,所以不同的操作系統就會安裝不同的庫文件。并且這里的緩沖區是庫級別的緩沖區,所以系統調用是無法刷新的,如果是操作系統級別的,那就會刷新,因為操作系統不會讓它白白占著空間的。

進程等待

我們之前說過,父進程要回收子進程的PCB來拿到子進程的退出信息,如果父進程不管不顧,子進程就會進入僵尸狀態,就會造成內存泄漏,這時就算kill -9也無能為力,因為誰也不能殺死一個已經死掉的進程。而父進程回收子進程就是通過進程等待

wait和waitpid

我們有兩種等待方式,分別是wait和waitpid,我們可以man查一下

這里的status是一個輸出型參數,通過給一個整型變量的地址,這個函數內部就可以將退出信息寫入到這個地址中,如果不想讓它寫入可以給NULL;pid就是要等待的子進程的pid,如果是-1的話,那么等待任一子進程,這時與wait等效options是確定父進程是阻塞等待還是非阻塞等待

我們再看一下返回值是什么意思

就是說:如果成功等待到了子進程結束,就返回子進程的PID;如果等待失敗(如果pid參數指定的子進程不存在或不是當前進程的子進程或是如果調用被一個信號中斷)就返回-1;如果非阻塞等待(WNOHANG)等待后,子進程狀態沒變,那么返回0。

知道了各個參數和返回值是什么意思,那我們就可以簡單的來使用一下wait和waitpid:

我們上面說過,任何進程最終的執行情況可以有兩個數字表明,一個是退出碼,一個是退出信號,如果收到退出信號,那么最終的退出碼沒有意義waitpid就是通過status這個輸出型參數拿到這兩個數字的,那么這兩個數字是怎么存在一個status中的呢?我們來看一下:

我們只用status中32個比特位中的低16位,也就是0-15位,如果進程沒有收到退出信號,那么8-15位就表示子進程的退出碼,所以我上面獲取退出碼時是先進行位右移8位,然后按位與上0xff;如果收到退出信號,那么0-6位表示收到什么退出信號,第七位表示core dump標志,這個標志先不用管,所以我上面是直接按位與上0x7f。

為了驗證,我們也可以故意給一個錯誤的代碼,比如訪問空指針,這時讓程序運行,看看父進程能否分析出子進程的退出信號

我們可以看到,父進程確實等待到了子進程的退出信號11

宏:WIFEXITED

其實不一定非得像上面那樣進行位操作才可以得到退出碼,我們還可以通過宏來得到退出碼或退出信號,像下面這樣

wait if exited這個表示如果進程是正常終止,就是沒有收到退出信號,那就返回真,所以我們用wait exit status來獲取退出碼;如果為假,我們用wait terminate signal來獲取退出信號。因為只要有退出信號,退出碼就沒意義,退出碼有意義時沒有退出信號,所以它們兩個只要根據不同情況獲取一個即可。

非阻塞等待

我們上面說過waitpid的第三個參數如果是0,那么就是阻塞等待如果是WNOHANG,就是非阻塞等待,什么是阻塞等待呢?其實就是父進程在等待子進程退出時如果什么都不做,就叫做阻塞等待如果父進程使用WNOHANG后waitpid后就會立即返回,不管是否有子進程退出,如果等到了子進程退出,返回值就是子進程的pid,如果沒有等到就返回0。因為waitpid只會運行一回,有可能等不到子進程,所以一般把它放進一個循環中,并且父進程執行完waitpid后還可以執行自己的工作,我們一般可以這樣去實現

進程結束之后只留下進程PCB,所以父進程肯定是通過子進程的PCB獲取退出碼和退出信號的,我們在Linux源碼中也確實可以看到

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

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

相關文章

【九十二】【算法分析與設計】875. 愛吃香蕉的珂珂,410. 分割數組的最大值,機器人跳躍問題,二分答案法

875. 愛吃香蕉的珂珂 - 力扣(LeetCode) 珂珂喜歡吃香蕉。這里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警衛已經離開了,將在 h 小時后回來。 珂珂可以決定她吃香蕉的速度 k (單位:根/小時)。每…

【活動】開源與閉源大模型:探索未來趨勢的雙軌道路

🌈個人主頁: 鑫寶Code 🔥熱門專欄: 閑話雜談| 炫酷HTML | JavaScript基礎 ?💫個人格言: "如無必要,勿增實體" 文章目錄 開源與閉源大模型:探索未來趨勢的雙軌道路引言一、開源大模型&#…

翻譯《The Old New Thing》- The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag

The importance of the FORMAT_MESSAGE_IGNORE_INSERTS flag - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071128-00/?p24353 Raymond Chen 2007年11月28日 FORMAT_MESSAGE_IGNORE_INSERTS 標志的重要性 簡要 文章討論了使用FormatMes…

評估企業的業務是否存在高風險的六個步驟

風險的幽靈使得組織別無選擇,只能改善各種網絡風險的總體管理。以下是一個基于信息安全論壇的IRAM2方法論的分步過程,網絡安全和風險從業者可以利用它來評估和管理信息風險。 第1步:范圍界定練習 范圍界定練習的目標是提供一個以業務為中心…

基于springboot+vue的招聘信息管理系統

開發語言:Java框架:springbootJDK版本:JDK1.8服務器:tomcat7數據庫:mysql 5.7(一定要5.7版本)數據庫工具:Navicat11開發軟件:eclipse/myeclipse/ideaMaven包:…

K8s的常用命令以及yaml文件的創建

目錄 一、聲明式管理方法:YAML文件 1、yaml文件簡介 2、yaml和json的主要區別: 3、YAML的語法格式 4、yaml文件組成部分 ①控制器定義 5、查看api資源版本標簽 6、編寫nginx-deployment.yaml資源配置清單 6.1創建資源對象 6.2查看創建的pod資源…

使用python將一段文本寫入一個txt文件中且先格式化文件名

有一段文本內容&#xff0c;有“標題”和“內容”組成。 任務&#xff1a;要將這段文本&#xff0c;存放到一個txt文件中&#xff0c;文件名為當天的日期加上“標題”內容。因為“標題”內可能有/<>之類的&#xff0c;還需要格式化一下。 已經將上述功能都寫成了函數&a…

安卓手機APP開發__近距離無線通信(NFC)概述

安卓手機&#xff21;&#xff30;&#xff30;開發&#xff3f;&#xff3f;近距離無線通信(NFC)概述 概述 近距離無線通信 (NFC) 是一組近距離無線技術&#xff0c;距離通常不超過 4 厘米才能 發起連接。通過 NFC&#xff0c;您可以在 NFC 標簽和 Android 設備之間&#xf…

【Redis】 String類型的內部編碼與使用環境

文章目錄 &#x1f343;前言&#x1f334;內部編碼&#x1f384;典型使用場景&#x1f6a9;緩存功能&#x1f6a9;計數&#xff08;Counter&#xff09;功能&#x1f6a9;共享會話&#xff08;Session&#xff09;&#x1f6a9;驗證碼功能 ?總結 &#x1f343;前言 本篇文章重…

Unity-Sprite Atlas+UGUI系統的運行原理

每日一句&#xff1a;別聽世俗耳語&#xff0c;看自己的風景就好 目錄 SA的原理&#xff1a; SA的優點&#xff1a; SA的缺點&#xff1a; DrawCall是什么&#xff1f; 批處理是什么&#xff1f; 我們先了解一下UGUI系統的運行原理吧&#xff01; 提到圖集優化&#xff0…

cocosCreator動態生成二維碼

cocosCreator 版本&#xff1a;3.7.2 開發語言&#xff1a;typeScript 我們在游戲開發中&#xff0c;經常會生成一個專屬于玩家個人的二維碼&#xff0c;比如說推廣、充值等功能。 接到這個任務&#xff0c;在網上找了下&#xff0c;還是有很多教程的。但是這些教程大部分都是用…

Ollydbg動態分析MessageBoxA輸出hellow world

一、目的 找到main函數找到調用的MessageBoxA函數 測試源碼 #include <iostream> #include <windows.h>int main() {MessageBoxA(NULL, "Hellow World", "Title", MB_OK);return 1; }二、快捷鍵 指令快捷鍵說明RestartCtrlF2重新開始調試S…

buu[HCTF 2018]WarmUp(代碼審計)

buu[HCTF 2018]WarmUp&#xff08;代碼審計&#xff09; 題目 訪問source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php…

MySQL基礎學習: SET FOREIGN_KEY_CHECKS = 0

文章目錄 一、介紹二、使用方法三、注意事項 一、介紹 在MySQL中&#xff0c;SET FOREIGN_KEY_CHECKS 0; 是一個特殊的命令&#xff0c;用于臨時禁用外鍵約束檢查。這在你執行一些涉及多個表并且可能違反外鍵約束的批量操作時非常有用。 為什么需要禁用外鍵約束檢查&#xf…

電腦鍵盤如何練習盲打?

電腦鍵盤如何練習盲打&#xff1f;盲打很簡單&#xff0c;跟著我做&#xff0c;今天教會你。 請看【圖1】&#xff1a; 【圖1】中&#xff0c;紅色方框就是8個基準鍵位&#xff0c;打字時我們左右手的8個手指就是放在這8個基準鍵位上&#xff0c;F鍵和J鍵上各有一個小突起&…

Spring6基礎筆記

Spring6 Log4j2 1、概述 1.1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 輕量級開源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并創立&#xff0c;其目的是用于簡化 Java 企業級應用的開發難度和開發周期。Spring的用途不僅限于服務器端的開發…

mysql圖形化界面及將mysql注冊成后臺程序

安裝圖形化界面版本 右鍵新建數據庫 字符集使用utf8防止以后數據庫中存在中文字符導致亂碼 將mysql注冊成后臺程序 cmd進入命令行界面 切換路徑到cd /mysql/bin 將mysql注冊成后臺程序 mysqld.exe --install mysql1 (失敗&#xff0c;說明沒有權限) 以管理員身份打開成功…

ASP.NET防止流量攻擊的措施

請求速率限制&#xff1a; // 在 Global.asax.cs 文件中 Application_BeginRequest 方法中添加以下代碼 protected void Application_BeginRequest() {// 檢查請求頻率&#xff0c;限制每個 IP 地址的請求次數if (RequestThrottler.IsRequestLimitExceeded(Context.Request.Use…

如何跨過robots協議的限制爬取內容?

在討論如何“跨過robots協議的限制爬取內容”之前&#xff0c;重要的是強調遵循網絡禮儀和法律法規的必要性。robots協議&#xff08;Robots Exclusion Standard&#xff09;是網站所有者向網絡爬蟲&#xff08;包括搜索引擎和其他自動化工具&#xff09;傳達其爬取意愿的一種方…

SYSTEM文件夾介紹(sys文件夾、deley文件夾、USART 文件夾、SysTick、printf函數、fputc函數、半主機模式)

參考 http://t.csdnimg.cn/P9H6x 一、sys文件夾介紹 在上述介紹的 sys 文件夾中&#xff0c;涉及了一些與系統控制、中斷管理、低功耗模式、棧頂地址設置、系統時鐘初始化以及緩存配置等相關的函數。以下是對每個功能的簡要分析&#xff1a; 1.中斷類函數&#xff1a; sys_n…