Linux——進程控制(一)進程的創建與退出

目錄

一、進程創建

1.寫時拷貝

2.創建多個進程

二、進程終止

1.main函數的返回值

2.bash中的$??

3.自定義退出碼

4.C語言的錯誤碼

5.錯誤碼與退出碼的區別

6.代碼異常終止

7.exit函數

8.總結


一、進程創建

在之前,我們學過linux中的非常重要的函數——fork。他可以從已存在進程中創建一個新進程,新進程為子進程,而原進程為父進程

1.寫時拷貝

我們知道,fork之后,父子代碼共享,經常會出現同一個變量,父子通過操作的不同,這個變量的值也不同,這個時候就會發生寫時拷貝。寫時拷貝是如何進行的呢?

通過這張圖可以看到,fork之后數據段變成了只讀, 子進程需要對數據進行寫入,就得需要寫時拷貝,寫時拷貝需要重新申請空間,進行拷貝,再修改頁表,這都是操作系統在幫我們處理的,那么操作系統怎么知道你這一份數據需要進行寫時拷貝呢?

父進程創建子進程的時候首先將自己的讀寫權限修改成只讀,然后再創建子進程,這些操作用戶并不知道,可能對某些數據進行寫入,這樣在頁表處就會進行權限判斷,發現用戶沒有權限,操作系統此時就會介入,操作系統會判斷用戶的操作

如果該區域本該是可讀可寫的,是操作系統修改為只讀的,因此操作系統會認為用戶的操作不算錯誤,就會觸發重新申請內存再拷貝內容的策略機制,這就是寫時拷貝。

如果出錯,就直接報錯,不做額外處理。

寫時拷貝完成后,再將對應的內容在頁表中修改為可讀可寫(沒有進行寫實拷貝的內容依然是只讀的)。這樣用戶就可以正常訪問了。

這是一種惰性分離,每次發生寫時拷貝都要開辟空間,將寫時拷貝的時間越往后延遲,操作系統就有更多的資源


這里還有一個小問題:你要寫入的時候寫就完事了,為何還要拷貝一份呢?

因為覆蓋和修改是不一樣的,很多情況,我們只是想要修改內容的某一部分,這樣先拷貝再修改會更合適一點。

2.創建多個進程

我們知道fork的常規用法如下兩種

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

如果要創建多個進程來幫我們處理,應該怎么做呢?? 直接上代碼

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>#define N 10typedef void (*callback)();void Work()
{int cnt = 10;while(cnt){printf("我是一個子進程, pid: %d, ppid :%d, cnt:%d\n",getpid(),getppid(),cnt--);sleep(1);}
}void CreateProcess(int n,callback cb)
{int i = 0;for(;i<n;i++){sleep(1);pid_t id = fork();if(id == 0){//child                                                                    printf("子進程創建成功: %d\n",i);cb();exit(0);}}
}int main()
{CreateProcess(N,Work);sleep(100);return 0;
}

這代碼對于學過fork的我們來講,并不算難,多了一個函數指針而已,下面是運行代碼。

二、進程終止

進程退出的場景如下三種

  • 代碼運行完畢,結果正確
  • 代碼運行完畢,結果不正確
  • 代碼異常終止

1.main函數的返回值

我們寫C語言程序時,main函數一般都會return 0。只要執行到了return語句,證明我們的代碼肯定是運行完畢了的,只是結果還不知道是否正確

在多進程環境中,我們創建子進程的目的是完成父進程不方便辦的事,那我們怎么知道子進程辦得怎么樣,雖然我們可以打印出來看看結果,但在有一些情況下不方便或者不能打印出來看看,此時就可以通過return的值來查看的,main函數的返回值,就叫做進程的退出碼,0通常表示成功,非0表示失敗。父進程可以通過獲取子進程退出碼(即main函數的返回值)來得知子進程做得咋樣。

成功的還好,知道你吧事情辦得很好,如果返回非0,代表這個事沒辦好,我們得知道是因為什么原因失敗的,我們可以用不同的數字表示不同的原因。但純數字能表示出錯的原因,但是不便于人閱讀,因此有一個函數交 strerror 函數。

如下可以打印出strerror各個數字代表的出錯原因

有很多很多原因?

2.bash中的$??

在bash命令中輸入echo $? 可以打印出最近一個子進程執行完畢時的退出碼,有點類似于之前我們學習的環境變量,變量名為?,加了$可以打印出變量里的內容。

如下代碼中return 10,執行該進程,bash最后獲取到的子進程退出碼就為10

但是我們繼續執行echo $? 后面退出碼就會變成0,因為echo也是bash的一個子進程,執行echo語句后,echo語句就是最后一個子進程了,echo又是正常退出的,因此再輸入echo $? 得到的值為0。

main函數的退出碼是可以被父進程獲取的,用來判斷子進程的運行結果?

3.自定義退出碼

退出碼可以使用C語言內置的,也可以自定義,自己對退出碼做解釋,因為退出碼退出多少(也就是return 返回多少是你自己設置的)?

如下就是自定義的退出碼,如果你的代碼根據用戶的操作出現了錯誤,可以返回響應的值,來知道發生了什么錯誤。

4.C語言的錯誤碼

在學習C語言的時候,我們接觸過一個名叫 errno 的全局變量,他會在程序在運行過程中調用某些庫函數或者系統接口出錯的時候,被自動設置。也是記錄最后一次出錯的信息。

如下代碼,只讀的方式打開一個不存在文件,我們看一下erron的變化與出錯信息

發現錯誤碼為2,錯誤信息為沒有該文件

5.錯誤碼與退出碼的區別

  • 錯誤碼通常是衡量調用庫函數或者系統調用接口的調用情況。(系統調用也能更改錯誤碼是因為Linux是用C語言寫的,提供了C式接口)
  • 退出碼通常是一個進程退出的時候,他的退出結果。

他們兩個共同的地方在于當失敗的時候,用來衡量函數、進程出錯時的詳細原因。

如下,讓錯誤碼與退出碼保持了一致

6.代碼異常終止

前面五點主要學習的是進程正常退出的問題,可能會有出錯碼和退出碼,如果一個進程異常終止,那么他的退出碼也就沒有了意義

比如代碼中存在 /0 錯誤,又比如段錯誤,棧溢出等等,程序就會崩潰,進程就異常了,就不會繼續運行了,本質是操作系統將該進程殺掉了,操作系統會用信號的方式將進程殺掉。

輸入 kill -l 可以查看 kill命令的信號?

這里我們一直運行一個進程,然后輸入kill -8 + 進程pid,就可以通過浮點數錯誤的方式終止該進程。輸入其他方式殺死,也會有相應的錯誤報告。?

?因此,查看進程是否出現異常,我們只需看有沒有收到信號即可

7.exit函數

C語言退出函數 exit() ,括號內部可以添加數字,這也是退出碼的一種。?

exit與return的區別在于

在非main函數中return 并不會終止進程,main函數會終止進程。

在任意函數中exit都會終止進程。

8.總結

查看進程運行完畢,結果是否正確,只需要看退出碼即可

查看進程異常終止,只需要查看收到的信號是什么即可。

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

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

相關文章

Git 將dev1.0分支的某些commit合并到dev分支上

前言&#xff1a;dev1.0是新開發的需求內容&#xff0c;但是部分熱更內容在此分支提交&#xff0c;如今需要把熱更的內容發到dev環境&#xff0c;但是dev1.0新需求未開發完畢&#xff0c;不可更新到dev環境。 現在在dev1.0分支 git pull #拉取當前分支最新內容git log #查看最…

3. 文字陰影

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>文字陰影</title><style>*{margin: …

速賣通店鋪營銷秘籍:如何巧妙運用活動提升轉化率

對于速賣通賣家而言&#xff0c;想要提升店鋪的成交率&#xff0c;除了依賴付費推廣外&#xff0c;更重要的是如何通過店鋪營銷來吸引和留住潛在買家。今天&#xff0c;我們就來深入探討一下速賣通店鋪營銷的幾個關鍵策略。 首先&#xff0c;我們要明確一點&#xff0c;速賣通平…

IDEA中的Structure模塊使用詳解

IDEA中的Structure模塊使用詳解 類方法的展示 從左往右介紹&#xff1a; 1、最開頭的 m 標識是表示為方法&#xff0c;如出現 f 標識則表示為屬性&#xff1b; 2、m后面跟著的是方法或者屬性的訪問修飾符&#xff1a; #紅色關閉的鎖表示為private&#xff1b; #圓圈表示不帶…

使用Docker搭建一款實用的個人IT工具箱——It-Tools

作為程序員&#xff0c;在日常工作中&#xff0c;需要借助一些工具來提高我們工作效率&#xff0c;IT-Tools是為開發人員度身打造的一套便捷在線工具。它提供全面功能&#xff0c;使開發者能以更高效方式完成任務。經由IT-Tools&#xff0c;開發人員能輕松應對各類技術挑戰&…

qt QRadioButton 及QButtonGroup 使用

QRadioButton 放在組合框QGroupBox中&#xff0c;再點擊時&#xff0c;即使有多個QRadioButton按鈕&#xff0c;同時選中的也就只有一個。 如下圖所示&#xff0c; 對于多個QRadioButton&#xff0c;每個按鈕都寫一個槽函數是不太明智的選擇&#xff0c;需要將QRadioButton放在…

海外服務器ping丟包怎么辦?

一般跨境企業比如說跨境電商、游戲等等都會有海外各個節點服務器的需求&#xff0c;包括對海外服務器的需求。當使用海外服務器時 &#xff0c;難免會出現一些問題&#xff0c;比如說丟包。那么&#xff0c;當海外服務器丟包的話&#xff0c;該如何處理呢&#xff1f; 說到丟包…

「MySQL」增刪查改

在操作數據庫中的表時&#xff0c;需要先使用該數據庫&#xff1a; use database;新增 創建表 先用 use 指定一個數據庫,然后使用 create 新增一個表 比如建立一個學生表 mysql> use goods; mysql> create table student(-> name varchar(4),-> age int,-> …

Compose 介紹

Compose 介紹 Android Compose 是 Google 官方推出的用于構建原生 Android UI 的現代工具包。它使用 Kotlin 語言編寫&#xff0c;可以幫助開發人員更輕松、更快速地創建精美、響應式和高性能的 Android 應用。 Compose 的優勢 聲明式 UI&#xff1a; Compose 使用聲明式 UI…

IIS部署.Net 7項目

&#x1f468; 作者簡介&#xff1a;大家好&#xff0c;我是Taro&#xff0c;前端領域創作者 ?? 個人主頁&#xff1a;唐璜Taro &#x1f680; 支持我&#xff1a;點贊&#x1f44d;&#x1f4dd; 評論 ??收藏 文章目錄 前言一、發布項目二、解決發布失敗1.發布失敗2.托管…

深入理解計算機系統筆記

1.1 嵌套的數組 當我們創建數組的數組時&#xff0c;數組分配和引用的一般原則也是成立的。 例如&#xff0c;聲明 int A[5][3]; 等價于下面的聲明 typedef int row3_t[3]; row3_t A[5] 要訪問多維數組的元素&#xff0c;編譯器會以數組起始為基地址&#xff0c; (可能需…

【Ai生態開發】Spring AI上架,打造專屬業務大模型,AI開發再也不是難事!

大家好 這里是蘇澤 后端是工作 ai是興趣 對于ai的產生我的立場是擁抱ai的 是希望拿他作為提升能力的工具 那么這一篇帶大家來學習如何使用ai打造一個專屬的業務大模型 需求 就是說假設現在有一個 商城系統 里面有查詢訂單的api和獲取商品購買方式的api 用戶只需要輸入 “…

C++二叉搜樹的實現(遞歸和非遞歸)

目錄 1.什么是二叉搜索樹 2.二叉搜索樹的查找 3.二叉搜索樹插入 4.二叉搜索樹的刪除 1.刪除的節點只有左子樹或者右子樹 2.刪除節點左右子樹都有的情況 5.代碼 1.什么是二叉搜索樹 左節點的值小于根節點 右節點大于根節點 左右子樹也滿足上面兩個條件 例&#xff1a;…

平臺工程與安全

平臺工程不是為了取代DevOps&#xff0c;而是DevOps的進一步演進和發展。本文介紹了DevOps和平臺工程&#xff0c;以及對于安全的意義。原文: Platform Engineering and Security: A Very Short Introduction 中國云南大理的日落 我是一名 DevOps 工程師&#xff0c;個人還是希…

c# 調用存儲過程

1.調用返回OUT的存儲過程 a.調用OUT字符串的存儲過程&#xff1b; #region 連接數據庫/// <summary>/// 連接數據庫/// </summary>/// <param name"connStatus"></param>/// <param name"dbNode"></param>/// <ret…

Android WebView訪問網頁+自動播放視頻+自動全屏+切換橫屏

一、引言 近期&#xff0c;我發現電視家、火星直播等在線看電視直播的軟件都已倒閉&#xff0c;而我奶奶也再無法通過這些平臺看電視了。她已六十多歲&#xff0c;快七十歲啦。這些平臺的倒下對我來說其實沒有多大的影響&#xff0c;但是對于文化不多的她而言&#xff0c;生活中…

Linux下的時間同步,以及ntp時間服務器配置流程

Linux下的時間同步&#xff0c;以及ntp時間服務器配置流程 概論常見時間操作命令Linux下的系統時間配置Linux硬件的時間的設置系統時間和硬件時間的同步NTP服務器時間的同步NTP服務的安裝NTP的時間同步定時任務里的時間同步配置文件同步時間 概論 但在Linux下&#xff0c;系統…

SpringBoot中間件簡介

Spring Boot是一個Java框架&#xff0c;它提供了一系列中間件來簡化應用程序的開發和集成。以下是一些常見的Spring Boot中間件&#xff1a; Web中間件&#xff1a; Servlet容器&#xff08;內嵌Tomcat、Jetty或Undertow&#xff09; Spring MVC&#xff08;用于構建Web應用程…

HBuilderX創建uniapp項目使用 tailwindcss

文章目錄 一、創建package.json文件二、打開終端 yarn / npm 安裝依賴三、創建 vue.config.js文件四、創建postcss.config.js文件五、創建tailwind.config.js文件六、App.vue文件的style中引入tailwindcss 一、創建package.json文件 {"devDependencies": {"aut…

藍橋杯算法 一.

分析&#xff1a; 本題記錄&#xff1a;m個數&#xff0c;異或運算和為0&#xff0c;則相加為偶數&#xff0c;后手獲勝。 分析&#xff1a; 369*99<36500&#xff0c;369*100>36500。 注意&#xff1a;前綴和和后綴和問題