Linux:進程:進程控制

進程創建

在Linux中我們使用fork函數創建新進程:

fork函數

fork函數是Linux中的一個系統調用,用于創建一個新的進程,創建的新進程是原來進程的子進程

返回值:如果子進程創建失敗,返回值是-1。如果子進程創建成功,對于父進程而言,fork的返回值是子進程的pid(子進程的進程號);對于子進程而言,fork的返回值是0。

讓父子進程分別打印fork函數的返回值和自己的PID:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t pid;      //parent_idpid_t cid;      //child_pidprintf("Before fork Process id: %d\n", getpid());cid = fork();printf("After fork, Process id: %d\n", getpid());printf("fork_function return: %d\n", cid);sleep(5);return 0;
}

實驗結果:

調用fork后,內核中的fork代碼會執行:

? 分配新的內存塊和內核數據結構給?進程

? 將?進程部分數據結構內容拷???進程

? 將?進程添加到系統進程列表當中

? fork返回,調度器開始調度

子進程被創建好后,父子進程會并發執行后續代碼

父子進程內存空間獨立

上文說到,fork函數會把父進程的代碼和數據拷貝給子進程,以此來保證進程之間的獨立性,但實際上,為了節省內存空間和提高運行效率,只有當子進程的代碼和數據發生變化時,才會為子進程開辟一塊內存空間,并將父進程的代碼和數據拷貝給子進程,這被稱為寫時拷貝

而在寫時拷貝之前,父子進程的虛擬地址相同,并且通過頁表映射后指向同一處物理地址

而在寫時拷貝之后,父子進程的虛擬地址仍然相同,只是會映射到不同的物理地址

進程終止

進程終?的本質是釋放進程申請的相關內核數據結構和對應的數據和代碼。

進程退出的三種情況:

1.代碼運?完畢,結果正確

2.代碼運?完畢,結果不正確

3. 代碼異常終?

為了判斷進程終止是哪種情況,進程在結束時會將退出碼和退出信號返回給父進程,其中,退出信號用于判斷進程是否異常,退出碼用于判斷進程運行結果是否正確

如何獲取退出碼和退出信號,我們在進程等待部分再做介紹,這里先介紹常見的退出碼:

可以使?strerror函數來獲取退出碼對應的描述。

返回不同的退出碼:

1.使用 return n

2.使用void exit(int status)或void _exit(int status),二者區別如下:

return n和exit(n)等效

進程等待

進程等待的目的:

1.檢查子進程的任務執行

2.避免產生僵尸進程

進程等待的方法

wait函數

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* status);

返回值:

成功返回被等待進程 pid ,失敗返回-1 。

參數:

status:輸出型參數,獲取?進程退出碼?, 不關?則可以設置成為 NULL

一個父進程可能有多個子進程,而wait函數等待的是任意子進程

因此,推薦使用waitpid函數:

 pid_ t waitpid(pid_t pid, int *status, int options);

返回值:

當正常返回的時候 waitpid 返回收集到的?進程的進程 ID ;

如果設置了選項 WNOHANG, ?調?中 waitpid 發現沒有已退出的?進程可收集 , 則返回 0 ;

如果調?中出錯 , 則返回-1, 這時 errno 會被設置成相應的值以指?錯誤所在;

參數:

pid :

Pid=-1, 等待任?個?進程。與 wait 等效。

Pid>0. 等待其進程 ID 與 pid 相等的?進程。

status: 輸出型參數,為了便于調用,可以使用以下兩個宏:

WIFEXITED(status): 若為正常終??進程返回的狀態,則為真。(查看進程是否是正常退出) WEXITSTATUS(status): 若 WIFEXITED ?零,提取?進程退出碼。(查看進程的退出碼)

options:

默認為 0 ,表?阻塞等待

WNOHANG: 非阻塞等待,若 pid 指定的?進程沒有結束,則 waitpid() 函數返回 0 ,不予等待。若正常結束,則返回該?進程的 ID 。

status

status用于記錄子進程的退出信號和退出碼:

前7位為退出信號,第8位為core dump標志(不關心),9~16位為退出碼

若退出信號非0,表明進程異常

若退出信號為0,表明進程正常運行

若退出碼非0,表明運行結果錯誤

若退出碼非0,表明運行結果正常

阻塞等待與非阻塞輪詢等待對比

阻塞等待:

int main(){pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__);return 1;} else if( pid == 0 ){ //childprintf("child is run, pid is : %d\n",getpid());sleep(5);exit(257);} else{int status = 0;pd_t ret = waitpid(-1, &status, 0);//阻塞式等待,等待5S printf("this is test for wait\n");if( WIFEXITED(status) && ret == pid ){printf("wait child 5s success, child return code is:%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;}

父進程阻塞等待成功

雖然返回的是257,但由于退出碼只取8位,所以返回1:

非阻塞輪詢等待:

void handler() {printf("臨時任務\n");sleep(1);}int main() {pid_t pid;pid = fork();if (pid < 0) {printf("%s fork error\n", __FUNCTION__);return 1;} else if (pid == 0) {  // childprintf("child is run, pid is : %d\n", getpid());sleep(5);exit(1);} else {int status = 0;pid_t ret = 0;do {ret = waitpid(-1, &status, WNOHANG);  //?阻塞式等待if (ret == 0) {printf("child is running\n");}handler();} while (ret == 0);if (WIFEXITED(status) && ret == pid) {printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));} else {printf("wait child failed, return.\n");return 1;}}return 0;}

可以看到父進程一邊執行自己的“臨時任務”,一邊詢問子進程是否結束,直到子進程結束,等待結束:

進程替換

我們之前雖然用fork創建了子進程,但是子進程和父進程執行的還是同樣的代碼,很多時候我們創建子進程就是為了去專門執行某一任務,這就需要用到進程替換,進程替換是通過特定的接?,把磁盤上另外的?個程序的代碼和數據加載到調?原先進程的地址空間中。

替換原理

?fork創建?進程后執?的是和?進程相同的程序(但有可能執?不同的代碼分?),?進程往往要調??種exec函數以執?另?個程序。當進程調??種exec函數時,該進程的??空間代碼和數據完全被新程序替換,從新程序的啟動例程開始執?。調?exec并不創建新進程,所以調?exec前后該進程的id并未改變。

替換函數

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

這些函數如果調?成功則加載新的程序從啟動代碼開始執?,不再返回;如果調?出錯則返回-1?

這里把子進程替換為一個能夠讀入并執行命令的程序:

#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h> 
int main(int argc, char* argv[])
{pid_t id=fork();if(id==0){     char**  myargv=&argv[1];                                                                                                                                                    execvp(myargv[0],myargv);}waitpid(id,NULL,0);return 0;
}

可以看到子進程可以收集并執行命令

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

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

相關文章

day1-小白學習JAVA---JDK安裝和環境變量配置(mac版)

JDK安裝和環境變量配置 我的電腦系統一、下載JDK1、oracle官網下載適合的JDK安裝包&#xff0c;選擇Mac OS對應的版本。 二、安裝三、配置環境變量1、終端輸入/usr/libexec/java_home -V查詢所在的路徑&#xff0c;復制備用2、輸入ls -a3、檢查文件目錄中是否有.bash_profile文…

Python項目--基于機器學習的股票預測分析系統

1. 項目介紹 在當今數字化時代&#xff0c;金融市場的數據分析和預測已經成為投資決策的重要依據。本文將詳細介紹一個基于Python的股票預測分析系統&#xff0c;該系統利用機器學習算法對歷史股票數據進行分析&#xff0c;并預測未來股票價格走勢&#xff0c;為投資者提供決策…

計算機視覺與深度學習 | 基于YOLOv8與光流法的目標檢測與跟蹤(Python代碼)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 目標檢測與跟蹤 關鍵實現邏輯檢測-跟蹤協作機制?特征點選擇策略?運動…

Java集合及面試題學習

知識來源沉默王二、小林coding、javaguide 1、ArrayList list.add("66") list.get(2) list.remove(1) list.set(1,"55") List<String> listnew ArrayList<>(); 底層是動態數組 添加元素流程&#xff1a;判斷是否擴容&#xf…

OSPF --- LSA

文章目錄 一、OSPF LSA&#xff08;鏈路狀態通告&#xff09;詳解1. LSA通用頭部2. OSPFv2 主要LSA類型a. Type 1 - Router LSAb. Type 2 - Network LSAc. Type 3 - Summary LSAd. Type 4 - ASBR Summary LSAe. Type 5 - AS External LSAf. Type 7 - NSSA External LSA 3. LSA泛…

Spring Boot 框架介紹及 Spring Boot 與 Spring 實現對比

在日常 Java Web 開發中&#xff0c;Spring 框架幾乎是繞不開的技術體系。傳統的 Spring 項目因其靈活強大而被廣泛應用&#xff0c;但隨著項目規模擴大與業務復雜度提升&#xff0c;XML 配置繁瑣、部署復雜等問題逐漸顯現。為此&#xff0c;Spring Boot 應運而生。 Spring Boo…

基于CNN卷積神經網絡和GEI步態能量提取的視頻人物步態識別算法matlab仿真

目錄 1.算法運行效果圖預覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 4.1 GEI步態能量提取 4.2 CNN卷積神經網絡原理 5.算法完整程序工程 1.算法運行效果圖預覽 (完整程序運行后無水印) 2.算法運行軟件版本 matlab2024b/matlab2022a 3.部分核心程序 &…

創建型模式:建造者模式

什么是建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;是一種創建型設計模式&#xff0c;它將一個復雜對象的構建過程與其表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。簡單來說&#xff0c;建造者模式允許您一步一步創建復雜對象&#xff0c;而…

Linux `init 5` 相關命令的完整使用指南

Linux init 5 相關命令的完整使用指南—目錄 一、init 系統簡介二、init 5 的含義與作用三、不同 Init 系統下的 init 5 行為1. SysVinit&#xff08;如 CentOS 6、Debian 7&#xff09;2. systemd&#xff08;如 CentOS 7、Ubuntu 16.04&#xff09;3. Upstart&#xff08;如 …

RabbitMQ常見面試題回答重點

文章目錄 什么是消息隊列&#xff1f;為什么需要消息隊列消息隊列的模型消息隊列常見名詞如何保證消息不丟失&#xff1f;&#xff08;可靠性&#xff09;如何保證消息不重復/業務冪等性如何保證消息有序性如何處理消息堆積消息隊列設計為推送還是拉取 / 推拉模式優點無法路由的…

欣佰特攜數十款機器人相關前沿產品,亮相第二屆人形機器人和具身智能行業盛會

2025年4月15日至16日&#xff0c;備受關注的第二屆中國人形機器人與具身智能產業大會已在北京成功舉行。作為國內前沿科技及產品服務領域的重要參與者&#xff0c;欣佰特科技攜眾多前沿產品精彩亮相&#xff0c;全方位展示了其在人形機器人與具身智能領域的創新產品。 在本次大…

Docker安裝 (centos)

1.安裝依賴包&#xff1a; sudo yum install -y yum-utils device-mapper-persistent-data lvm2 2.刪除已有的 Docker 倉庫文件&#xff08;如果有&#xff09;&#xff1a; sudo rm -f /etc/yum.repos.d/docker-ce.repo 3.添加阿里云的 Docker 倉庫&#xff1a; sudo yum…

Vue接口平臺學習十——接口用例頁面2

效果圖及簡單說明 左邊選擇用例&#xff0c;右側就顯示該用例的詳細信息。 使用el-collapse折疊組件&#xff0c;將請求到的用例詳情數據展示到頁面中。 所有數據內容&#xff0c;綁定到caseData中 // 頁面綁定的用例編輯數據 const caseData reactive({title: "",…

服務器數據遷移指南

服務器數據遷移是將數據從一臺服務器轉移到另一臺服務器的過程&#xff0c;可能是為了硬件升級、云遷移、數據中心搬遷或服務整合。 以下是數據遷移的關鍵步驟和注意事項&#xff1a; 遷移前準備 制定遷移計劃 確定遷移范圍(全量/增量) 評估數據量和網絡帶寬 制定時間表和回…

25.解決中醫知識問答刪除歷史對話功能后端處理請求時拋出異常

ChatTest.vue:176 DELETE http://localhost:8080/api/chat/conversations/20 500 (Internal Server Error) deleteConversation ChatTest.vue:176 onClick ChatTest.vue:22 ChatTest.vue:185 刪除失敗 AxiosError {message: Request failed with status code 500, name: Axio…

記錄seatunnel排查重復數據的案例分析

文章目錄 背景分析檢查現象檢查B集群是否有異常&#xff0c;導致重復消費的分析同步任務 修復問題發現flink job 一直報異常修復問題 背景 使用seatunnel 同步數據從A 集群kafka 同步到B集群kafka,現象是發現兩邊數據不一致&#xff0c;每天10w級別會多幾十條數據 分析 檢查…

VSCode遠程圖形化GDB

VSCode遠程圖形化GDB 摘要一、安裝VSCode1、使用.exe安裝包安裝VSCode2、VSCode 插件安裝3、VSCode建立遠程連接 二、core dump找bug1、開啟core文件2、永久生效的方法3、編寫測試程序4、運行結果5、查看core段錯誤位置6、在程序中開啟core dump并二者core文件大小 三、gdbserv…

Android 中實現 GIF 圖片動畫

在 Android 中&#xff0c;ImageView 從 Android 9.0&#xff08;API 級別 28&#xff09; 開始原生支持 GIF 動畫&#xff0c;通過 AnimatedImageDrawable 類實現。在之前的版本中&#xff0c;ImageView 并不支持直接播放 GIF 動畫&#xff0c;只能顯示 GIF 的第一幀。 一、 …

【c語言】指針進階

目錄 1.字符指針 2.指針數組 3.數組指針 3.1 數組指針的定義 3.2 數組指針的使用 4.數組參數&#xff0c;指針參數 4.1 一維數組傳參 4.2 二維數組傳參 4.3 一級指針傳參 4.4 二級指針傳參 5.函數指針 6.函數指針數組 6.1函數指針數組的定義 6.2 函數指針數組…

極狐GitLab 項目 API 的速率限制如何設置?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 項目 API 的速率限制 (BASIC SELF) 引入于 15.10 版本&#xff0c;功能標志為rate_limit_for_unauthenticated_projects_api_…