【Linux系統】詳解,進程控制

前言:

? ? ? ? 上文我們講到了Linux中的虛擬空間地址,知道了一個進程對應一個虛擬地址空間,虛擬空間地址與物理地址之間通過頁表映射....【Linux】虛擬地址空間-CSDN博客

? ? ? ? 本文我們來講一講Linux系統是如何控制進程的!

? ? ? ? 如果喜歡本期文章,請點點關注吧!非常感謝佬的支持? ?_(:з」∠)_? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?


進程創建

fork函數

? ? ? ? fork函數是Linux系統提供的接口,其功能就是創建子進程。

? ? ? ? 既調用fork函數,系統就自動為我們創建好了子進程

#include<unistd.h>
pid_t fork();其中pid_t是Linux中的數據類型,相當于int,即為整型

? ? ? ? fork的返回值有兩個,對于父進程:返回子進程的pid,對于子進程:返回0

#include <stdio.h>
#include <unistd.h>int main()
{pid_t pid = fork();if(pid<0){   printf("創建失敗");}   else if(pid == 0){   //子進程printf("我是一個子進程:%d,這是我的父進程:%d\n",getpid(),getppid());}   else if(pid > 0){   printf("我是一個父進程:%d,這是我的父進程:%d\n",getpid(),getppid());}   
} 

? ? ? ? 對于fork原理的詳細介紹可參考【Linux】初見,進程概念-CSDN博客中的第四節“如何創建進程”,這里面有超級詳細的介紹!

fork的用法

? ? ? ? 一個父進程希望復制自己,使父子進程同時執行不同的代碼段。e.g. 父進程等待客戶端響應,生成子進程處理請求。

? ? ? ? 一個進程想要執行多個不同的代碼。e.g. 生成子進程調用exec函數。

fork失敗原因

? ? ? ? 系統中的進程太多了

? ? ? ? 用戶的進程數量超過了限制


進程終止

進程終止的本質就是進程結束,系統釋放資源:釋放進程申請的相關數據結構和對應的代碼與數據

進程退出的場景

? ? ? ? 1.代碼運行完畢,結果正確(退出碼為0)

? ? ? ? 2.代碼運行完畢,結果不正確(退出碼為非0)

? ? ? ? 3.代碼異常終止(進程接收到型號終止,退出碼無意義)

進程退出方法

正常退出:

? ? ? ? 1.從main函數返回

? ? ? ? 2.調用exit

? ? ? ? 3._exit

異常退出:

? ? ? ? 信號終止

退出碼

? ? ? ? 退出碼可以告訴我們進程終止時的狀態,0代表執行成功,非0則代表不成功

? ? ? ? 非0的退出碼中,一個值對應一個錯誤原因。可以使用strerror函數獲取退出碼對應的信息。

#include <stdio.h>
#include<string.h>int main()
{for(int i=0;i<200;i++){   printf("%d -> %s\n",i,strerror(i));                                                                                                                            }   
}
0 -> Success
1 -> Operation not permitted
2 -> No such file or directory
3 -> No such process
4 -> Interrupted system call
5 -> Input/output error
6 -> No such device or address
7 -> Argument list too long
8 -> Exec format error
9 -> Bad file descriptor
10 -> No child processes
11 -> Resource temporarily unavailable
12 -> Cannot allocate memory
13 -> Permission denied
14 -> Bad address
15 -> Block device required
16 -> Device or resource busy
17 -> File exists
18 -> Invalid cross-device link
19 -> No such device
20 -> Not a directory
21 -> Is a directory
22 -> Invalid argument
23 -> Too many open files in system
24 -> Too many open files
25 -> Inappropriate ioctl for device
26 -> Text file busy
27 -> File too large
28 -> No space left on device
29 -> Illegal seek
30 -> Read-only file system
31 -> Too many links
32 -> Broken pipe
33 -> Numerical argument out of domain
34 -> Numerical result out of range
35 -> Resource deadlock avoided
36 -> File name too long
37 -> No locks available
38 -> Function not implemented
39 -> Directory not empty
40 -> Too many levels of symbolic links
41 -> Unknown error 41
42 -> No message of desired type
43 -> Identifier removed
44 -> Channel number out of range
45 -> Level 2 not synchronized
46 -> Level 3 halted
47 -> Level 3 reset
48 -> Link number out of range
49 -> Protocol driver not attached
50 -> No CSI structure available
51 -> Level 2 halted
52 -> Invalid exchange
53 -> Invalid request descriptor
54 -> Exchange full
55 -> No anode
56 -> Invalid request code
57 -> Invalid slot
58 -> Unknown error 58
59 -> Bad font file format
60 -> Device not a stream
61 -> No data available
62 -> Timer expired
63 -> Out of streams resources
64 -> Machine is not on the network
65 -> Package not installed
66 -> Object is remote
67 -> Link has been severed
68 -> Advertise error
69 -> Srmount error
70 -> Communication error on send
71 -> Protocol error
72 -> Multihop attempted
73 -> RFS specific error
74 -> Bad message
75 -> Value too large for defined data type
76 -> Name not unique on network
77 -> File descriptor in bad state
78 -> Remote address changed
79 -> Can not access a needed shared library
80 -> Accessing a corrupted shared library
81 -> .lib section in a.out corrupted
82 -> Attempting to link in too many shared libraries
83 -> Cannot exec a shared library directly
84 -> Invalid or incomplete multibyte or wide character
85 -> Interrupted system call should be restarted
86 -> Streams pipe error
87 -> Too many users
88 -> Socket operation on non-socket
89 -> Destination address required
90 -> Message too long
91 -> Protocol wrong type for socket
92 -> Protocol not available
93 -> Protocol not supported
94 -> Socket type not supported
95 -> Operation not supported
96 -> Protocol family not supported
97 -> Address family not supported by protocol
98 -> Address already in use
99 -> Cannot assign requested address
100 -> Network is down
101 -> Network is unreachable
102 -> Network dropped connection on reset
103 -> Software caused connection abort
104 -> Connection reset by peer
105 -> No buffer space available
106 -> Transport endpoint is already connected
107 -> Transport endpoint is not connected
108 -> Cannot send after transport endpoint shutdown
109 -> Too many references: cannot splice
110 -> Connection timed out
111 -> Connection refused
112 -> Host is down
113 -> No route to host
114 -> Operation already in progress
115 -> Operation now in progress
116 -> Stale file handle
117 -> Structure needs cleaning
118 -> Not a XENIX named type file
119 -> No XENIX semaphores available
120 -> Is a named type file
121 -> Remote I/O error
122 -> Disk quota exceeded
123 -> No medium found
124 -> Wrong medium type
125 -> Operation canceled
126 -> Required key not available
127 -> Key has expired
128 -> Key has been revoked
129 -> Key was rejected by service
130 -> Owner died
131 -> State not recoverable
132 -> Operation not possible due to RF-kill
133 -> Memory page has hardware error

? ? ? ? 使用echo $?,可以打印出最近一個程序的退出碼。

? ? ? ? 退出碼是進程的性質之一,所以退出碼會保存到進程的PCB中。

_exit函數

#include<unistd.h>
void _exit(int status);在任何地方調用_exit函數,都會讓當前進程結束
并以給定的值作為退出碼退出

exit函數

#include<unistd.h>
void exit(int status);與_exit函數功能類似
都是以指定的退出碼,退出當前進程

區別

? ? ? ? _exit函數系統調用,而exit是C語言提供。

? ? ? ? 使用exit函數退出時,會進行緩沖區的刷新。反之_exit則不會。

舉個例子說明:

????????程序結束刷新緩沖區,信息打印在屏幕上,反之沒有信息打印

????????感興趣的朋友可以看看這篇文章,這里有詳細的緩沖區刷新介紹【Linux】LInux下第一個程序:進度條-CSDN博客

#include <stdio.h>
#include<string.h>
#include<unistd.h>int main()
{printf("yuzuriha");sleep(1);exit(0);                                                                                                                                                           
}

#include <stdio.h>
#include<string.h>
#include<unistd.h>int main()
{printf("yuzuriha");                                                                                                                                                sleep(1);_exit(0);
}


進程等待

進程等待的必要性

? ? ? ? 1.之前我們講過子進程的退出后,子進程回進入僵尸狀態,必須要被父進程回收才行。若子進程一直沒有被父進程回收,就會一直處于僵尸狀態,進而造成內存泄漏。

? ? ? ? 2.進程被創造出來執行任務,結果如何,是成功、失敗還是異常,這是父進程要得知的必要信息。

? ? ? ? 所以回收子進程是必要的,父進程通過進程等待的方式,回收子進程進程資源、獲取子進程的退出信息。

進程等待的方法

wait方法
#include<sys/types.h>
#include<sys/wait.h>pid_t wait(int* status);返回值:等待成功返回對應的子進程pid,失敗則返回-1參數status:為輸出型參數,可以獲取子進程的退出碼若不需要,可以傳NULL忽略這個參數
waitpid函數
#include<sys/types.h>
#include<sys/wait.h>pid_ t waitpid(pid_t pid, int *status, int options);

下面詳細介紹一下每一個參數:

pid_t pid

參數pid:-1,表示可以等待任意一個子進程。

參數pid:>0,表示只能等待當前這個進程的子進程。

status

? ? ? ? 如上面所講,status是一個輸出型參數,由操作系統填充,我們可以通過status獲取進程狀態

? ? ? ? status并不是一個簡單的整型,細節如下:

? ? ? ? 1.status是一個低16位有效的int,通過位劃分存儲子進程的信息

? ? ? ? 2.正常終止的情況下:低7位全為0,15~8存放退出碼

? ? ? ? ? ? ? ? 獲取退出碼:WEXITSTATUS(status)

? ? ? ? 3.非正常退出:退出碼無意義,第7位存放標志,6~0存放信號編號

? ? ? ? ? ? ? ? 判斷一個進程是否位正常退出:WIFEXITED(status),正常為真。

options

????????options的默認值是0,表示阻塞等待

????????options為:WNOHANG時表示非阻塞等待

? ? ? ? 簡而言之,阻塞等待就是等待子進程結束的過程中,父進程不能運行。而非阻塞等待,就是等待過程中父進程可以執行自己的代碼。

? ? ? ? 當參數為:WNOHANG時,waitpid會進行非阻塞輪詢等待結束,返回>0(pid)本次調用結束,但子進程還沒有退出,返回0調用失敗,返回<0;


進程程序替換?

? ? ? ? 程序替換就是字面上的意思,替換掉原有的程序,先來直接看看效果

#include <stdio.h>                                                                                                                                                     
#include<unistd.h>int main()
{printf("開始\n");execl("/usr/bin/ls","ls","-l",NULL);printf("結束\n");
}

? ? ? ? ?我們可以看到執行就第一個printf打印出了結果,第二行就執行就程序替換,將原來的程序替換為了ls指令。

替換原理

????????exec系列函數,其功能就是用新的程序替換原本的程序。

? ? ? ? 如圖,替換程序的本質是將物理內存中的數據,用新數據覆蓋,頁表中的物理地址重新覆蓋填寫,其他的不動。

注意:

? ? ? ? 1.一旦程序替換成功,就會去執行新代碼了,舊代碼以及不復存在了。

? ? ? ? 2.exec系列函數只有在失敗的時候才有返回值,既只要返回就是失敗。

? ? ? ? 3.程序替換并沒有創建新進程,只是進行了數據的覆蓋。

認識全部exec函數

execl
int execl(const char* path , const char* arg , ...)l:代表list,以鏈表的形式傳參
path:路徑+程序名,表示要執行誰
arg:平時怎么寫指令,這里就怎么寫。表示如何執行注:一定要以NULL結尾!!!
#include <stdio.h>                                                                                                                                                     
#include<unistd.h>int main()
{printf("開始\n");execl("/usr/bin/ls","ls","-l",NULL);printf("結束\n");
}

不僅可以替換系統程序,也可以替換我們自己寫的程序:

#include <stdio.h>
#include<unistd.h>int main()
{printf("開始\n");execl("./x","./x",NULL);                                                                                                                                           printf("結束\n");
}

? ? ? ? 我們知道數據和代碼父子進程默認是共享的,那程序替換對父進程有影響嗎?

? ? ? ? 沒有,因為數據和代碼都會進行寫時拷貝

execlp
int execlp(const char* file , const char* arg , ...)l:表示list,以鏈表的形式傳參
p:表示環境變量PATHfile:有了PATH環境變量,我們就不用寫路徑了。直接寫我們要執行的程序名即可
arg:同上,與我們平時寫的指令無異但必須以NULL結尾
#include <stdio.h>
#include<unistd.h>int main()
{printf("開始\n");execlp("ls","ls","-l",NULL);                                                                                                                                       printf("結束\n");
}

execv
int execv(const char* path , char* const argv[])v:表示vector,用數組的方式傳參數組中,依舊想要以NULL結尾
#include <stdio.h>
#include<unistd.h>int main()
{char* const argv[]={(char* const)"ls",(char* const)"-l",NULL};  printf("開始\n");execv("/usr/bin/ls",argv);                                                                                                                                         printf("結束\n");
}

?execvp
int execvp(const char* file , char* const argv[])v:vector,以數組形式傳參
p:環境變量PATH

同上,就不舉例了

execvpe
int execvpe(const char* flie , char* const argv[] , char* cosnt envp[])相比上面,多了一個e
e:環境變量!傳入envp數組,那被替換的進程的環境變量會被evnp[]直接覆蓋
這會導致我們無法使用原來的環境變量

? ? ? ? 所以我們一般采用新增環境變量的方式,而不是直接覆蓋。

? ? ? ? 法一:調用系統調用:putevn(char* string)新增環境變量,再調用其他exec函數實現

? ? ? ? 法二:調用系統調用:putevn(char* string)新增環境變量,調用execvpe時,傳入環境變量指針:environ

execle
int execle(const char* path , char* const argv .... , char* cosnt envp[])同上
execve
int execve(const char* path , char* const argv[] ... , char* cosnt envp[])同上

值得一提的是execve的系統調用,而其他函數都是C語言提供的

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

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

相關文章

Matplotlib(五)- 繪制子圖

文章目錄一、子圖概述1. 子圖介紹2. 子圖布局2.1 網格布局2.2 自由布局二、繪制等分區域子圖1. 使用 plt.subplot() 繪制子圖示例&#xff1a;繪制多個子圖示例&#xff1a;工業月度同比情況2. 使用 plt.subplots() 繪制子圖示例&#xff1a;繪制多個子圖示例&#xff1a;部分國…

C++中互斥鎖、共享鎖深度解析

一&#xff0c;互斥鎖互斥鎖&#xff08;Mutex&#xff0c;全稱 Mutual Exclusion&#xff09;是并發編程中用于保護共享資源的核心同步機制。它通過確保同一時間僅有一個線程訪問臨界區&#xff08;Critical Section&#xff09;&#xff0c;解決多線程環境下的數據競爭和不一…

Qt中的QWebSocket 和 QWebSocketServer詳解:從協議說明到實際應用解析

前言 本篇圍繞 QWebSocket 和 QWebSocketServer&#xff0c;從協議基礎、通信模式、數據傳輸特點等方面展開&#xff0c;結合具體接口應用與實戰案例進行說明。 在實時網絡通信領域&#xff0c;WebSocket 技術以其獨特的全雙工通信能力&#xff0c;成為連接客戶端與服務器的重要…

機器學習 —— 決策樹

機器學習 —— 決策樹&#xff08;Decision Tree&#xff09;詳細介紹決策樹是一種直觀且易于解釋的監督學習算法&#xff0c;廣泛應用于分類和回歸任務。它通過模擬人類決策過程&#xff0c;將復雜問題拆解為一系列簡單的判斷規則&#xff0c;最終形成類似 “樹” 狀的結構。以…

車規MCU軟錯誤防護技術的多維度分析與優化路徑

摘要&#xff1a;隨著汽車電子技術的飛速發展&#xff0c;微控制單元&#xff08;MCU&#xff09;在汽車電子系統中的應用日益廣泛。然而&#xff0c;大氣中子誘發的單粒子效應&#xff08;SEE&#xff09;對MCU的可靠性構成了嚴重威脅。本文深入探討了軟錯誤防護技術在車規MCU…

原生微信小程序實現語音轉文字搜索---同聲傳譯

效果展示 ![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/23257ce3b6c149a1bb54fd8bc2a05c68.png#pic_center 注意&#xff1a;引入同聲傳譯組件請看這篇文章 1.search.wxml <view class"search-page"><navigation-bar title"搜索" …

Wireshark安裝過程缺失vc_runtimeMinimum_x64.msi文件,安裝 Visual C++ Redistributable

一、我大意了 一開始是Npcap裝不上。 在這個網站下的&#xff1a; Wireshark (kafan58.com) 安裝程序&#xff1a; 安裝過程&#xff1a; 無語死了&#xff0c;感覺被騙了......外網下的才是最正版的。 二、外網正版 下載最新的4.4.8版本Wireshark重新安裝 2.1 vc_runtime…

高通平臺Wi-Fi Display學習-- 調試 Wi-Fi Display 問題

4.1 調試 WFD 性能 4.1.1 通過啟用調節器模式驗證 WFD 當系統設為調節器模式時,設備的運行時鐘將達到峰值。要在系統中啟用調節器模式,應 在序列中輸入以下命令: 1. adb shell stop mpdecision 2. adb shell echo 1→/sys/devices/system/cpu/cpu1/online 3. adb shell…

5G專網與SD-WAN技術融合:某飲料智能工廠網絡架構深度解析

隨著工業互聯網的快速發展&#xff0c;制造業正從傳統的生產模式向智能化、數字化方向轉型。某飲料智能工廠項目創新性地引入了5G專網與SD-WAN技術&#xff0c;形成了“連接-計算-應用-安全”的全鏈條網絡架構。本文將深入剖析這兩種技術在智能工廠中的應用場景、部署架構&…

Java項目:基于SSM框架實現的公益網站管理系統【ssm+B/S架構+源碼+數據庫+畢業論文+答辯PPT+遠程部署】

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本公益網站就是在這樣的大環境下誕生&#xff0c;其可以幫助管理者在短時間內處理完畢龐大的數據信息&#x…

向華為學習——IPD流程體系之IPD術語

第一章 IPD體系 1.1集成產品開發IPD Integrated Product Development,IPD是一種領先的、成熟的產品開發的管理思想和管理模式。它是根據大量成功的產品開發管理實踐總結出來的,并被大量實踐證明的高效的產品開發模式。通過IPD,可建立起基于市場和客戶需求驅動的集成產品開…

落霞歸雁:從自然之道到“存內計算”——用算法思維在芯片里開一條“數據高速航道”

作者 落霞歸雁&#xff08;CSDN首發&#xff0c;轉載請注明&#xff09; 段落一 現象&#xff1a;當“摩爾”老去&#xff0c;數據卻在狂奔 過去 30 年&#xff0c;CPU 頻率翻了 60 倍&#xff0c;而 DRAM 帶寬只翻了 20 倍。算力與帶寬的剪刀差&#xff0c;讓“計算”變成“等…

StyleX:Meta推出的高性能零運行時CSS-in-JS解決方案

簡介 StyleX 是由 Meta 開發的零運行時 CSS-in-JS 解決方案&#xff0c;在構建時將樣式編譯為靜態 CSS&#xff0c;消除運行時開銷。 核心特性 零運行時開銷 – 構建時編譯為靜態 CSS類型安全 – 完整的 TypeScript 支持原子化 CSS – 自動生成原子化類名&#xff0c;最小化…

LINUX 85 SHElL if else 前瞻 實例

問題 判斷用戶是否存在 id user id $user變量判斷vsftpd軟件包被安裝 rpm -q vsftpd rpm -ql vsftpd >& null[rootweb ~]# rpm -ql vsftpd >/dev/null 2>&1 您在 /var/spool/mail/root 中有郵件yum install vsftpd 內核主版本判斷 uname -rcut -d[rootweb ~]#…

2025 年非關系型數據庫全面指南:類型、優勢

非關系型數據庫的分類與特點隨著數據量呈指數級增長和數據類型日益多樣化&#xff0c;傳統關系型數據庫在處理海量非結構化數據時面臨著嚴峻挑戰。非關系型數據庫&#xff08;NoSQL&#xff09;應運而生&#xff0c;它摒棄了傳統關系模型的約束&#xff0c;采用更靈活的數據存儲…

深度殘差網絡ResNet結構

Deep Residual Learning for Image Recognition&#xff0c;由Kaiming He、Xiangyu Zhang、Shaoqing Ren和Jian Sun于2016年發表在CVPR上 1512.03385 (arxiv.org)https://arxiv.org/pdf/1512.03385 下圖中&#xff0c;左側為VGG19網絡&#xff0c;中間為34層的普通網絡&#xf…

python筆記--socket_TCP模擬瀏覽器實現

""" 1,導包 2,創建TCP套接字 3,建立連接 4,拼接客戶端請求報文 5,發送請求報文 6,接收響應報文 7,過濾出html頁面 8,保存為html文件 9,關閉套接字 """ # 1,導包 import socket # 2,創建TCP套接字 tcp_socketsocket.socket(socket.AF_INET,socket…

西門子PLC基礎指令4:置位指令 S、復位指令 R

布爾指令 1、置位指令 S Setbit 是要進行置位操作的地址的首地址&#xff0c;N 是從該首地址開始連續置位的位數 。 LD I0.0 // 裝載輸入繼電器I0.0的狀態&#xff08;當I0.0為ON時&#xff0c;執行后續指令&#xff09; S Q0.0, 3 // 從Q0.0開始&#xff0c;連續置位3…

2.3 子組件樣式沖突詳解

Vue2組件樣式沖突的成因與解決方案組件樣式沖突的根本原因在Vue單頁面應用中&#xff0c;所有組件的DOM結構最終都會合并到同一個index.html 頁面中。若子組件未使用scoped屬性&#xff0c;其樣式會默認全局生效&#xff0c;導致不同組件中相同選擇器&#xff08;如h1、.contai…

26-數據倉庫與Apache Hive

1.數據倉庫 是什么&#xff1f;解決什么&#xff1f;1.1 數據倉庫Data Warehouse 數倉 / DW 是一個用于存儲、分析、報告的數據系統.目的&#xff1a;構建面向分析的集成數據環境&#xff0c;分析結構為企業提供決策支持。數倉專注于分析數倉本身不“”生產“”數據&#xff0c…