linux--------------進程控制(下)

一、進程等待

1.1 進程等待必要性

  • 子進程退出后,若父進程不管不顧,可能會產生 “僵尸進程”,進而造成內存泄漏。
  • 進程一旦變為僵尸狀態,即使使用?kill -9?也無法將其殺死,因為無法殺死一個已死的進程。
  • 父進程需要了解子進程的任務完成情況,比如子進程運行結束后結果是否正確,是否正常退出。
  • 父進程通過進程等待的方式,回收子進程資源并獲取其退出信息。

1.2 進程等待的方法

wait()?函數

wait()?函數用于阻塞等待子進程的結束,并回收其資源。以下是一個簡單的示例代碼:

#include <sys/wait.h>
#include <stdio.h>int main() {pid_t child_pid = fork();if (child_pid == 0) {// 子進程執行任務exit(42);  // 子進程退出碼42} else {int status;pid_t terminated_pid = wait(&status);  // 阻塞等待if (WIFEXITED(status)) {printf("子進程 %d 退出碼: %d\n", terminated_pid, WEXITSTATUS(status));}}return 0;
}
waitpid()?函數

waitpid()?函數的原型為?pid_t waitpid(pid_t pid, int *status, int options);,它可以更靈活地等待指定子進程的結束。

1.3 獲取子進程?status

wait?和?waitpid?都有一個?status?參數,這是一個輸出型參數,由操作系統填充。若傳遞?NULL,表示不關心子進程的退出狀態信息;否則,操作系統會根據該參數將子進程的退出信息反饋給父進程。

status?不能簡單地當作整型來看待,可將其視為位圖,具體細節可參考下面的圖片(只研究?status?低 16 比特位):

狀態位說明
低8位(0-7)子進程退出碼 (正常終止時有效)
第8位(8-15)信號編號 (被信號終止時有效)
其他標志位通過宏檢測狀態類型(如WIFEXITED)

1.4 阻塞和非阻塞

核心結論
  • 本質區別

    • 阻塞(Blocking):調用者線程暫停執行,直到操作完成(如數據到達、資源就緒)。

    • 非阻塞(Non-blocking):調用立即返回,無論操作是否完成,需通過輪詢或事件通知獲取結果。

  • 選擇依據

    • 阻塞:適合簡單邏輯、單任務場景,代碼直觀但資源利用率低。

    • 非阻塞:適合高并發、實時響應需求,需配合多路復用(如epoll)或異步通知(如回調)

深度解析
運行機制對比
特性阻塞模式非阻塞模式
線程狀態掛起(Sleeping)持續運行(Running)
CPU 占用低(等待時不消耗 CPU)高(需輪詢檢查狀態)
響應延遲操作完成后立即響應需主動檢測或等待通知
代碼復雜度低(線性執行)高(需處理中間狀態和錯誤碼)
典型應用場景

以下是阻塞和非阻塞模式的典型應用代碼示例:

阻塞模式示例

#include <stdio.h>
#include <fcntl.h>int main() {int fd = open("file.txt", O_RDONLY);  char buf[1024];  read(fd, buf, sizeof(buf));  // 阻塞直到數據就緒  printf("Data: %s\n", buf);  return 0;
}

非阻塞模式示例

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>#define BUFFER_SIZE 1024int main() {int sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);  struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080);server_addr.sin_addr.s_addr = INADDR_ANY;connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));  char data[BUFFER_SIZE] = "Hello, Server!";int len = strlen(data);while (1) {  if (send(sockfd, data, len, MSG_DONTWAIT) == -1) {  if (errno == EAGAIN) {  usleep(1000);  // 數據未就緒,短暫等待后重試  continue;  }  }  break;  }  close(sockfd);return 0;
}

二、進程程序替換

2.1 替換原理

使用?fork?創建子進程后,子進程執行的是與父進程相同的程序(但可能執行不同的代碼分支)。若子進程想執行一個全新的程序,可通過進程的程序替換來實現。當進程調用一種?exec?函數時,該進程的用戶空間代碼和數據會完全被新程序替換,并從新程序的啟動例程開始執行。調用?exec?并不會創建新進程,因此調用前后該進程的 ID 不會改變。

2.2 替換函數

函數名參數傳遞方式PATH 搜索環境變量典型用途
execl參數列表(可變參數)繼承當前環境已知絕對路徑的固定參數調用
execv參數數組(char *[]繼承當前環境動態構建參數的固定路徑調用
execlp參數列表繼承當前環境執行 PATH 中的命令(如 Shell)
execvp參數數組繼承當前環境動態執行 PATH 中的命令
execle參數列表自定義環境變量需嚴格控制環境的場景
execvpe參數數組自定義環境變量動態參數 + 自定義環境

2.3 函數解釋

這些函數如果調?成功則加載新的程序從啟動代碼開始執?,不再返回。
如果調?出錯則返回-1
所以exec函數只有出錯的返回值?沒有成功的返回值

2.4 命名理解

  • l(list):表示參數采用列表形式。
  • v(vector):參數使用數組。
  • p(path):有?p?則自動搜索環境變量?PATH
  • e(env):表示自己維護環境變量。

以下是調用示例:

#include <unistd.h>
#include <stdio.h>int main() {char *const argv[] = {"ps", "-ef", NULL};char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};execl("/bin/ps", "ps", "-ef", NULL);// 帶 p 的,可以使用環境變量 PATH,無需寫全路徑execlp("ps", "ps", "-ef", NULL);// 帶 e 的,需要自己組裝環境變量execle("ps", "ps", "-ef", NULL, envp);execv("/bin/ps", argv);// 帶 p 的,可以使用環境變量 PATH,無需寫全路徑execvp("ps", argv);// 帶 e 的,需要自己組裝環境變量execve("/bin/ps", argv, envp);// 如果 exec 調用失敗,會執行到這里perror("exec 調用失敗");return 1;
}

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

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

相關文章

docker 中跑faster-whisper 教程(1050顯卡)

之前我本地機器運行faster-whisper 會報錯類似 Could not load library libcudnn_ops_infer.so.8github 上也有類似的情況 &#xff1a;https://github.com/SYSTRAN/faster-whisper/issues/516#issuecomment-2785038635 缺少.so.8 文件&#xff0c;我通過以下方式&#xff0c;…

人大金倉數據庫dum文件進行備份數據和恢復數據

邏輯備份命令: sys_dump -U SYSTEM -d problem_dev -Fc -f /db_backup/kingbase/dump/problem_dev/problem_dev20240329.dmp用戶:SYSTEM 數據庫名:problem_dev 格式:自定義格式(-Fc) 輸出文件:/db_backup/kingbase/dump/problem_dev/problem_dev20240329.dmp sys_dump…

Java的Selenium元素定位-xpath

xpath其實就是一個path(路徑)&#xff0c;一個描述頁面元素位置信息的路徑&#xff0c;相當于元素的坐標xpath基于XML文檔樹狀結構&#xff0c;是XML路徑語言&#xff0c;用來查詢xml文檔中的節點。 絕對定位 從根開始找--/(根目錄)/html/body/div[2]/div/form/div[5]/button缺…

python-Leetcode 65.搜索旋轉排序數組

題目&#xff1a; 整數數組nums按升序排列&#xff0c;數組中的值互不相同 在傳遞給函數之前&#xff0c;nums在預先未知的某個小標K上進行了旋轉&#xff0c;使數組變為[nums[k], nums[k1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]&#xff0c;小標從0開始計數。…

學透Spring Boot — 010. 單元測試和Spring Test

系列文章目錄 這是CSDN postnull 博客《學透Spring Boot》系列的一篇&#xff0c;更多文章請移步&#xff1a;Postnull - 學透Spring Boot系列文章 文章目錄 系列文章目錄前言1. 基本概念UT 單元測試TDD 測試驅動開發UT測試框架Mock框架 3. Spring Test為什么要用Spring Test引…

Chrome 135 版本新特性

Chrome 135 版本新特性 一、Chrome 135 版本瀏覽器更新 ** 1. 第三方托管賬戶注冊遷移到 OIDC 授權碼流程** Chrome 135 將賬戶注冊的登錄頁面從營銷網站遷移到動態網站&#xff0c;同時也將 OpenID Connect (OIDC) 的隱式流程遷移到授權碼流程。這樣做的目的是進一步提升第…

Docker Swarm集群搭建與管理全攻略

文章目錄 一、節點準備二、初始化 manager 節點三、管理 swarm 集群中的 worker 節點1、添加 worker 節點2、查看 worker 節點3、刪除 worker 節點 四、管理 swarm 集群服務1、創建服務2、查看服務3、刪除服務 五、管理 swarm 節點服務1、節點標簽管理2、創建服務3、查看服務4、…

離線語音識別 ( 小語種國家都支持)可定制詞組

1產品介紹 離線語音模組采用神經網絡算法&#xff0c;支持語音識別、自學習等功能。運用此模組將 AI 技 術賦能產品&#xff0c;升級改造出語音操控的智能硬件 ( 例如風扇、臺燈、空調、馬桶、按摩椅、運 動相機、行車記錄儀等 ) 。支持全球多種語言識別&#xff0c;如中文…

Docker與VNC的使用

https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc 下載nvc 客戶端 https://downloads.realvnc.com/download/file/viewer.files/VNC-Viewer-7.12.0-Windows.exe 服務端 docker pull dorowu/ubuntu-desktop-lxde-vnc#下載成功 docker pull dorowu/ubuntu-desktop-l…

Linux系統學習Day0——了解和熟悉Linux系統的遠程終端登錄和數據傳輸

一、Windows系統與Linux系統虛擬機通過橋接進行網絡連接 &#xff08;一&#xff09;橋接模式 橋接模式是虛擬機網絡連接的一種常見方式&#xff0c;其核心原理是通過虛擬網卡將Linux虛擬機與宿主機的物理網卡建立橋接關系&#xff0c;使虛擬機能夠直接接入物理網絡。在該模式…

【開題報告+論文+源碼】基于springboot的農貿菜市場租位管理系統的設計與實現

項目背景與意義 隨著信息技術的快速發展和普及&#xff0c;信息化管理已成為各行業提升運營效率和服務質量的重要手段。農貿菜市場作為城市生活的重要組成部分&#xff0c;其管理效率和服務水平直接關系到市民的日常生活體驗。傳統的農貿菜市場租位管理方式往往存在信息不對稱、…

Codecademy—— 交互式編程學習的樂園

一、網站概述 Codecademy 是一家美國在線學習編程知識的網站&#xff0c;它為編程學習者提供了一種全新的學習方式。在如今眾多的編程學習平臺中&#xff0c;Codecademy 憑借其獨特的優勢脫穎而出&#xff0c;吸引了全球數百萬用戶。其目標是幫助更多人輕松學習編程&#xff0…

WEB安全--XSS--DOM破壞

一、前言 繼XSS基礎篇后&#xff0c;我們知道了三種類型的XSS&#xff0c;這篇文章主要針對DOM型XSS的原理進行深入解析。 二、DOM型XSS原理 2.1、什么是DOM 以一個形象的比喻&#xff1a; 網頁就像是一座房子&#xff0c;而 **DOM** 就是這座房子的“藍圖”或者“結構圖”。…

Linux系統遠程操作和程序編譯

Linux系統遠程操作和程序編譯 了解和熟悉Linux系統的遠程終端登錄、遠程圖形桌面訪問、 X圖形窗口訪問和FTP文件傳輸操作 網絡設置和用戶創建&#xff1a; 在虛擬機Ubuntu系統中&#xff0c;將網絡連接設置為“橋接模式”&#xff0c;并配置好IP和網關。確保其他Windows 10系統…

linux開發環境

1.虛擬機環境搭建 在 Ubuntu 系統中&#xff0c;打開&#xff08;如圖中顯示的窗口 &#xff09;常見快捷鍵有&#xff1a; Ctrl Alt T&#xff1a;這是最常用的打開終端的快捷鍵組合 &#xff0c;按下后會快速彈出一個新的終端窗口。 在 VMware 虛擬機環境中&#xff0c;若…

藍橋·20264-祝福語--找連續字串的長度

#include <iostream> using namespace std; int main() {// 請在此輸入您的代碼//最小字典序&#xff0c;一定是全a&#xff0c;找s的最長字串a,結果就是該字串長度加1&#xff08;t不能是s的子串&#xff09;//所以這道題就變成了&#xff0c;找s中字串a出現的長度strin…

7.第二階段x64游戲實戰-分析人物屬性

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 本次游戲沒法給 內容參考于&#xff1a;微塵網絡安全 上一個內容&#xff1a;6.第二階段x64游戲實戰-分析人物狀態 首先打開人物面板&#xff0c;查看人物的…

數組的常見算法一

注: 本文來自尚硅谷-宋紅康僅用來學習備份 6.1 數值型數組特征值統計 這里的特征值涉及到&#xff1a;平均值、最大值、最小值、總和等 **舉例1&#xff1a;**數組統計&#xff1a;求總和、均值 public class TestArrayElementSum {public static void main(String[] args)…

汽車電子筆記之:基于Tasking編譯器怎么制作庫文件并將庫文件集成進工程釋放

目錄 1、概述 2、庫工程創建、使用步驟 2.1、選擇對應的MCU型號及空工程 2.2、選擇需要封裝的代碼 2.3、將需要封裝的代碼復制到庫工程 2.4、整理庫工程工程屬性 2.5、預留不生成庫的.c源文件 2.6、編譯生成.a文件 2.7、將.a集成進工程 2.7.1、創建釋放給客戶的工程 …

[ctfshow web入門] web29

前置知識 eval: 把字符串按照 PHP 代碼來執行&#xff0c;例如eval(“echo 1;”);這個函數擁有回顯 system&#xff1a;使php程序執行系統命令&#xff0c;例如&#xff0c;system(“ls”);就是查看當前目錄&#xff0c;這個擁有回顯 preg_match&#xff1a;查找字符串是否匹配…