Linux:進程終止和進程替換

Linux:Linux:進程終止和進程替換

  • 一、進程終止
    • 1.1 進程退出場景和創建退出方式
  • 1.2 exit 和 _exit區別
  • 二、進程程序替換
    • 2.1 進程替換函數
    • 2.2 函數解釋及命名解釋
      • 函數解釋
      • 命名解釋
    • 2.3 單進程程序替換(無子進程)
      • 2.3.1 帶`l`函數進程替換(execl為例)
      • 2.3.2 帶`p‘函數進程替換(execlp為例)
      • 2.3.3 execv、execvp替換函數應用實例
    • 2.4 進程替換其他程序,調用運行其他語言程序
  • 三、進程替換時環境變量的繼承
    • 3.1 進程替換時,子進程環境變量由來
      • 3.2 為何父子進程間環境變量的繼承不受進程替換的影響
      • 3.3 子進程獲取環境變量的3種方式

一、進程終止

1.1 進程退出場景和創建退出方式

?進程退出有3種場景:代碼執行完畢,結果正確;代碼執行完畢,結果錯誤;代碼異常終止!

?而進程退出的常見方式主要分為以下兩大類:

正常終止
從main返回
調用exit退出
調用_exit退出
異常終止ctrl c, 信號終止

1.2 exit 和 _exit區別

? exit 和 _exit都可以直接終止進程。但_exit是系統調用接口,而exit為函數調用,底層封裝了exit。
?不同的是,exit終止進程時,會刷新緩沖區,執行用戶的清理函數,關閉流等操作;而_exit則是直接“粗暴”的退出進程,不做任何其他工作!!

在這里插入圖片描述

二、進程程序替換

?fork()創建子進程時,子進程執行的代碼和數據都是父進程的一部分。如果我們想讓子進程執行全新的代碼,訪問全新的數據,我們可以采用一種技術 —— 程序替換!而進程替換可以將命令行參數和環境變量傳遞給被替換程序的main()函數參數!!

2.1 進程替換函數

?進程替換函數有6種以exec開頭的函數,統稱為exec函數。

 #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 execvpe(const char *file, char *const argv[], char *const envp[]);

?而exec函數底層都封裝了系統調用接口execve的瘋轉,以實現不同的需求!

 #include <unistd.h>int execve(const char *filename, char *const argv[], char *const envp[]);

2.2 函數解釋及命名解釋

函數解釋

  1. 如果這些函數調用成功,也就意味著進程替換成功。此時重新加載新的程序,從啟動代碼開始執行,并且不再返回。即進程替換后,執行新程序,執行完后直接退出!!
  2. 如果進程替換函數執行失敗,此時返回值設為-1。
  3. exec函數只有出錯的返回值,沒有成功的返回值。

命名解釋

  • l(list):參數采用列表形式。
  • v(vector):參數采用數組。
  • p(path):帶p表示執行程序時,OS會自帶去環境變量PATH中查找路徑。
  • e(env):表示自己維護環境變量。

2.3 單進程程序替換(無子進程)

2.3.1 帶l函數進程替換(execl為例)

?下面我們在一段代碼的開頭和結尾分別輸出打印相關信息,然后兩段信息輸出代碼直接調用execl替換ls -a-l

【源代碼】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main()
{printf("pid: %d, ecec command begin!\n", getpid());//進程替換,執行ls指令相關程序execl("/usr/bin/ls", "ls", "-a", "-l", NULL);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

【運行結果】:

在這里插入圖片描述

【函數參數原型解釋】:


在這里插入圖片描述



在這里插入圖片描述


2.3.2 帶`p‘函數進程替換(execlp為例)

【源代碼】:(頭文件省略)

int main()
{printf("pid: %d, ecec command begin!\n", getpid());execlp("pwd", "pwd", NULL);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

【運行結果】:

在這里插入圖片描述

【函數參數原型解釋】:
在這里插入圖片描述
在這里插入圖片描述

2.3.3 execv、execvp替換函數應用實例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main()
{char *const argv[] = {"ls","-l","-a",NULL};printf("pid: %d, ecec command begin!\n", getpid());// 和execl、execlv類似,只不過下面函數時通過指針數組的方式,指明替換程序的執行方式!!execv("/usr/bin/ls", argv);execvp("ls", argv);printf("pid: %d, ecec command end!\n", getpid());return 0;
}

2.4 進程替換其他程序,調用運行其他語言程序

?上述所有的程序替換都是替換系統指令程序,那如何替換自己寫的程序。
?下面我們在c程序中創建子進程,讓子進程發送進程替換一段c++可執行程序,并且父進程等待子進程!!

【待替換C++程序】:

#include <iostream>int main()
{std::cout << "hello c++!" << std::endl;std::cout << "hello c++!" << std::endl;std::cout << "hello c++!" << std::endl;return 0;
}

【主代碼C程序】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>extern char **environ;int main()
{pid_t id = fork();if(id == 0){printf("pid: %d, ecec command begin!\n", getpid());execl("./mytest", "mytest");//替換C++程序//替換失敗,執行下面代碼printf("pid: %d, ecec command end!\n", getpid());exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}

【運行結果】:

在這里插入圖片描述

  • 為啥在c程序中,可以直接替換c++程序?根本原因在于exec函數發生的是進程替換,任何語言程序一旦運行起來就變成了進程,便可發生進程替換。系統大于一切!!

三、進程替換時環境變量的繼承

3.1 進程替換時,子進程環境變量由來

?環境變量是數據,所有可以通過地址空間實現父子間通過寫時拷貝的方式共享數據 —— 環境變量。所以當通過exec函數進行進程替換時,子進程的環境變量是直接從父進程來的。

3.2 為何父子進程間環境變量的繼承不受進程替換的影響

?父進程和子進程間通過寫時拷貝的方式,讓環境變量別子進程繼承,從而實現環境變量的全局性!但為何調用exec函數進行進程替換后,環境變量沒有發生修改,變為被替換程序的環境變量?

?原因很簡單,程序替換,只替換新程序的代碼和數據,環境變量不會被替換!!

3.3 子進程獲取環境變量的3種方式

  1. 操作系統直接將環境變量傳遞給子進程,子進程直接用。或者直接通過execle、execvpe的最后一個參數直接傳遞給子進程!

【實例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;int main()
{pid_t id = fork();if(id == 0){execle("./mytest", "mytest", NULL, environ);//進程替換,直接將environ傳遞給子進程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}
  1. 直接構造自己的環境變量表傳遞給子進程。

【實例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
extern char **environ;int main()
{pid_t id = fork();if(id == 0){execle("./mytest", "mytest", NULL, environ);//進程替換,直接將environ傳遞給子進程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){char *const envp[] = {"MYENV1 = 111111111111111111","MYENV2 = 111111111111111111","MYENV3 = 111111111111111111",NULL};execle("./mytest", "mytest", NULL, envp);//直接將自己構造的函數變量表envp傳遞給子進程}return 0;
}
  1. 借助putenv(),新增環境變量給父進程然后傳遞給子進程

【實例】:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>extern char **environ;int main()
{pid_t id = fork();if(id == 0){char *myenv = "MYENV = 111111111111111111";putenv(myenv);//將環境變量MYENV添加到父進程環境變量表中execl("./mytest", "mytest");//直接傳遞給子進程exit(1);}pid_t rid = waitpid(-1, NULL, 0);if(rid == id){printf("wait pid: %d success!!!\n", rid);}return 0;
}

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

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

相關文章

ArduPilot開源飛控之AP_VisualOdom

ArduPilot開源飛控之AP_VisualOdom 1. 源由2. 類定義2.1 類與構造函數2.2 枚舉類型2.3 公共方法2.4 消息處理2.5 其他功能2.6 私有成員 3. 框架設計3.1 啟動代碼 AP_VisualOdom::init3.2 消息處理3.2.1 AP_VisualOdom::handle_vision_position_delta_msg3.2.2 AP_VisualOdom::h…

買的Google賬號登錄,修改輔助郵箱收不到驗證碼?可能是個簡單的錯誤

這篇文章分享一個案例&#xff0c;購買了谷歌賬號以后如何修改輔助郵箱&#xff0c;修改輔助郵箱的一些要點&#xff0c;以及常見的一個錯誤。 一、案例回放 這個朋友昨天在我的一個視頻下面留言說買了谷歌賬號以后&#xff0c;想修改輔助郵箱地址&#xff0c;但是輸入了輔助…

中英雙語介紹加拿大多倫多(Toronto)

中文版 多倫多概述 多倫多&#xff08;Toronto&#xff09;是加拿大最大的城市&#xff0c;也是北美地區重要的經濟、文化和金融中心。以下是對多倫多的詳細介紹&#xff0c;包括其經濟地位、金融中心、人口、地理位置、高等教育、移民政策、著名景點和居住的名人等方面的信息…

【Git】本地版本控制

Git 是一個分布式版本控制系統&#xff0c;用于跟蹤文件的更改&#xff0c;通常用于源代碼管理。它的設計目的是為了協同工作和版本管理&#xff0c;讓多個開發人員能夠高效地合作開發和維護代碼。 Git環境配置 在官網可以找到對應下載&#xff1a;Git - Downloads (git-scm.c…

【WebRTC實現點對點視頻通話】

介紹 WebRTC (Web Real-Time Communications) 是一個實時通訊技術&#xff0c;也是實時音視頻技術的標準和框架。簡單來說WebRTC是一個集大成的實時音視頻技術集&#xff0c;包含了各種客戶端api、音視頻編/解碼lib、流媒體傳輸協議、回聲消除、安全傳輸等。對于開發者來說可以…

avcodec_send_packet函數阻塞

用ffmpeg4.1.4開發一個播放器&#xff0c;解碼過程如下&#xff0c;在每個函數前設置標志&#xff0c;測試發現程序阻塞在avcodec_send_packet函數。 while(true){av_read_frameavcodec_send_packetavcodec_receive_frameav_packet_unref } 解釋如下&#xff1a; avcodec_se…

嵌入式Linux:如何學好嵌入式?

目錄 方法步驟 1、 基礎知識 2、 學習linux 3、 學習嵌入式linux 4、深入學習 嵌入式書籍推薦 Linux基礎 Linux內核 研發方向 硬件基礎 方法步驟 1、 基礎知識 目的:能看懂硬件工作原理,但重點在嵌入式軟件,特別是操作系統級軟件。 科目:數字電路、計算機組成原理…

Unity3D游戲 RPG

叢林探險游戲 人物進行探險游戲 擁有登錄&#xff0c;首頁&#xff0c;3D物體旋轉瀏覽的功能&#xff0c;還能進行種植樹等功能

【異常錯誤】‘NoneType‘ object has no attribute ‘GetSubstructMatches‘

出現的錯誤信息&#xff1a; AttributeError: Caught AttributeError in DataLoader worker process 0. Original Traceback (most recent call last): File "/home/mapengsen/anaconda3/envs//lib/python3.8/site-packages/torch/utils/data/_utils/worker.py", l…

【matlab 路徑規劃】基于改進遺傳粒子群算法的藥店配送路徑優化

一 背景介紹 本文分享的是一個基于訂單合并的訂單分配和路徑規劃聯合優化&#xff0c;主要背景是騎手根據客戶需求&#xff0c;從藥店取藥之后進行配送&#xff0c;配送的過程中考慮路徑的長度、客戶的服務時間窗、車輛的固定成本等要素&#xff0c;經過建模和優化得到最優的配…

C# WinForm —— 38 SplitContainer介紹

1. 簡介 將頁面拆分成兩個大小可以調整的區域&#xff0c;中間有一個拆分條&#xff0c;可以拖動拆分條來調整左右區域的大小 2. 屬性 屬性解釋(Name)控件ID&#xff0c;在代碼里引用的時候會用到BoderStyle邊框樣式&#xff1a;None、FixedSingle、Fixed3DAutoScroll當控件…

力扣 225 用隊列實現棧 記錄

題目描述 請你僅使用兩個隊列實現一個后入先出&#xff08;LIFO&#xff09;的棧&#xff0c;并支持普通棧的全部四種操作&#xff08;push、top、pop 和 empty&#xff09;。實現 MyStack 類&#xff1a; void push(int x) 將元素 x 壓入棧頂。 int pop() 移除并返回棧頂元素…

C++ 引用做函數返回值

作用&#xff1a;引用是可以作為函數的返回值存在的 注意&#xff1a;不要返回局部變量引用 用法&#xff1a;函數調用作為左值 示例&#xff1a; 運行結果&#xff1a;

程序員熬夜看歐洲杯被“凍住”,呼吸困難……

2024歐洲杯接近尾聲&#xff0c;更是激發球迷興趣。由于時差關系&#xff0c;很多球迷熬夜看球&#xff0c;啤酒、宵夜成了標配。然而&#xff0c;在這份歡樂背后&#xff0c;也隱藏著健康風險。 日前&#xff0c;浙江杭州29歲的程序員單先生熬夜與朋友看完球賽后開車回家&…

零基礎STM32單片機編程入門(九)IIC總線詳解及EEPROM實戰含源碼視頻

文章目錄 一.概要二.IIC總線基本概念1.總體特征2.通訊流程 三.EEPROM介紹1.M24C08基本介紹2.向M24C08寫一個字節時序圖3.從M24C08讀一個字節時序圖 四.GPIO模擬IIC驅動M24C08讀寫五.CubeMX工程源代碼下載六.講解視頻鏈接地址七.小結 一.概要 IIC(Inter&#xff0d;Integrated …

黑馬|最新AI+若依 |初識項目

本章主要內容是&#xff1a; 1.快速搭建了若依前后端項目在本地 2.實現了單表的增刪改查快速生成 文章目錄 介紹1.若依介紹2.若依的不同版本3.項目運行環境 初始化前后端項目1.下載若依項目2.初始化后端a.把表導入到數據庫中b.更改application.yml文件 3.初始化前端a.安裝依賴…

基于LoFTR_TRT項目實現LoFTR模型的trt推理與onnx推理,3060顯卡下320圖像30ms一組圖

本博文主要記錄了使用LoFTR_TRT項目將LoFTR模型導出為onnx模型&#xff0c;然后將onnx模型轉化為trt模型。并分析了LoFTR_TRT與LoFTR的基本代碼差異&#xff0c;但從最后圖片效果來看是與官網demo基本一致的&#xff0c;具體可以查看上一篇博客記錄。最后記錄了onnx模型的使用【…

WebAssembly場景及未來

引言 從前面的文章中&#xff0c;我們已經了解了 WebAssembly&#xff08;WASM&#xff09; 的基本知識&#xff0c;演進歷程&#xff0c;以及簡單的使用方法。通過全面了解了WebAssembly的設計初衷和優勢&#xff0c;我們接下來要知道在什么樣的場景中我們會使用 WASM 呢&…

在門店里造綠色氧吧!康養行業也這么卷了?

拼啥不如拼健康&#xff0c;現在的人算是活明白了&#xff0c;不但中老年人這樣想&#xff0c;年輕人也這樣干。你可能不知道&#xff0c;現在眾多健康養生門店&#xff0c;逐漸成了年輕人“組團養生”的好去處&#xff0c;也是他們吃喝玩樂之外的新興消費趨勢。 而在看得見的…

原理圖設計工作平臺:capture和capture CIS的區別在于有沒有CIS模塊

1環境:design entry CIS 2.參數設置命令options——preference&#xff08;7個選項卡colors/print&#xff0c;grid display&#xff0c;miscellaneous&#xff0c;pan and zoom&#xff0c;select&#xff0c;text editor和board simulation&#xff09; 1)顏色設置colors/p…