【進程替換】多進程程序替換原理 | 進程程序替換函數 | execlexecv | execlpexecvp

目錄

多進程程序替換

多進程程序替換原理

進程程序替換函數詳解

execl&execv

execlp&execvp

execle&execvpe?

execve


多進程程序替換

  • 我們想要進程替換的同時不影響舊的進程(使用多進程版)
  • fork創建子進程,讓子進程去替換執行新程序(因為替換進程本身不會創建新的進程)
  • 父進程依舊執行舊的進程,且等待子進程(非阻塞等待)
  • 父進程只等待子進程(阻塞等待)
  • 子進程可以替換系統指令,也可以替換我們自己的程序,只要是一個可執行程序都可以替換。
  • 兩全其美:既讓子進程完成了任務,又不能讓父進程受到影響

說明fork創建子進程完成任務:

  • 讓子進程執行父進程代碼的一部分
  • 讓子進程執行一個全新的程序
  • 基于進程間的獨立性原則。
  • fork創建的子進程默認在不修改的前提下,父子進程的數據和代碼時共享的。
  • 子進程發生了進程替換,相當于發生寫入,發生了寫時拷貝。
  • 執行一個全新的程序,父子進程是獨立的,所以不僅數據要寫時拷貝,代碼也要發生寫時拷貝。只要程序替換成功了,父子進程無論是代碼/數據在內核數據結構層面上,數據代碼層面上徹底分開了。

子進程發生程序替換:

  • 共享父進程的數據代碼
  • 暫停了把新程序的代碼和數據從磁盤到內存的加載/寫入
  • 發生寫時拷貝
  • 開啟加載/寫入(頁表的權限會改變)
  • 重新建立映射關系
 1: testexec.c 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execl("/usr/bin/ls","ls","-l","-a",NULL);                                                            16     exit(1);17   }18   //father19   int status = 0;20   pid_t rid = waitpid(id,&status,0);21   if(rid > 0)22   {23     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));24   }25   printf("testexec... end!\n");26   return 0;27 }//測試失敗
execl("/usr/bin/lsss","lsss","-l","-a",NULL);    

【測試成功】細看退出碼

【測試失敗】細看退出碼

?

多進程程序替換原理

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

進程程序替換函數詳解

前篇粗略的介紹了下替換函數,現在一個一個詳解介紹。使用所有的替換方法,并且認識函數參數的含義

  • OS中默認進程程序替換函數有6個庫函數和1個系統調用函數。
  • 其實有六種以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[]);
//系統調用函數
int execve(const char *path, char *const argv[], char *const envp[]);

execl&execv

  • l:list列表
  • int execl(const char *path, const char *arg, ...);?
  • path:表示替換程序的路徑(絕對/相對路徑均可)??怎樣找到可執行程序需告知
  • arg:可變參數,在命令行中怎么執行,就怎么傳參。??你想怎么執行
  • arg形成命令行參數表傳給ls指令的可執行程序main函數接收使用
  • 注意?最后必須以NULL結尾

  • V:Vector動態數組
  • int execv(const char *path, char *const argv[ ]);
  • path:表示替換程序的路徑(絕對/相對路徑均可)??怎樣找到可執行程序需告知
  • argv:指針數組(可變參數與其一個一個傳參,直接放到數組里面,傳數組即可)(帶入命令行參數表)
  • argv被當作命令行參數表傳給ls指令的可執行程序main函數接收使用
  • 字符串的類型是const char*變成char*需要強轉
  • 注意?最后必須以NULL結尾
  • 這兩個函數只是在傳參形式上發生了變化,實際上沒有區別。
  1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execl("/usr/bin/ls","ls","-l","-a",NULL);  //?                                                          16     exit(1);17   }//1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     char *const argv[] =16     {17       (char*)"ls",18       (char*)"-l",                                                                                       19       (char*)"-a",20       (char*)"--color",21       NULL22     };23     execv("/usr/bin/ls",argv); //?24     exit(1);25   }26   //father27   int status = 0;28   pid_t rid = waitpid(id,&status,0);29   if(rid > 0)30   {31     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));32   }33   printf("testexec... end!\n");34   return 0;                                                                                              35 }

execlp&execvp

  • p:環境變量PATH
  • 帶p的函數不用帶絕對/相對路徑傳遞參數了,表示用戶可以不傳遞替換程序的路徑(但是要傳遞可執行程序的文件名file)
  • 用戶可以不傳遞要執行的文件路徑(文件名要傳),直接告訴exec*,我要執行誰即可。
  • p:查找這個程序,系統會自動在環境變量PATH中進行查找。
  • int execlp(const char *file, const char *arg, ...);
  • int execvp(const char *file, char *const argv[ ]);
 1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     execlp("ls","ls","-l","-a",NULL);  //?                                                          16     exit(1);17   }//1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h>4 #include<sys/types.h>5 #include<sys/wait.h>6 7 int main()8 {9   printf("testexec.... begin!\n");10   pid_t id = fork();11   if(id == 0)12   {13     //child14     sleep(2);15     char *const argv[] =16     {17       (char*)"ls",18       (char*)"-l",                                                                                       19       (char*)"-a",20       (char*)"--color",21       NULL22     };23     execvp("ls",argv); //?24     exit(1);25   }26   //father27   int status = 0;28   pid_t rid = waitpid(id,&status,0);29   if(rid > 0)30   {31     printf("father wait success!,child exit code: %d\n",WEXITSTATUS(status));32   }33   printf("testexec... end!\n");34   return 0;                                                                                              35 }

execle&execvpe?

  • e:environment環境變量
  • int execle(const char *path, const char *arg, ...,char *const envp[ ]);
  • int execvpe(const char *file, char *const argv[ ],char *const envp[ ]);

  • bash有環境變量,也可以獲取命令行參數
  • bash創建父進程
  • fork創建子進程
  • 通過exec*等函數將環境變量表和命令行參數表交給可執行程序
  • 子進程運行起來,并使用兩張表

execve

🙂感謝大家的閱讀,若有錯誤和不足,歡迎指正。 下篇收尾?

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

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

相關文章

2008NOIP普及組真題 4. 立體圖

線上OJ&#xff1a; 一本通-1977&#xff1a;【08NOIP普及組】立體圖 核心思想&#xff1a; 本題采用模擬方法一個一個畫小方塊&#xff08;雖然畫的是立體空間的積木&#xff0c;但本質還是在二維平面上畫圖形&#xff09; 本題的難點在于&#xff1a; 1、如何確定二維平面畫…

tengine-docker鏡像制作

1.下載 wget https://tengine.taobao.org/download/tengine-3.0.0.tar.gz 或者直接下載這個包括下邊兩個配置文件了 https://download.csdn.net/download/cyw8998/89286114 2.編輯nginx.conf文件 #####user nobody; worker_processes 1;#error_log logs/error.log; #er…

淺析擴散模型與圖像生成【應用篇】(二十三)——Imagic

23. Imagic: Text-Based Real Image Editing with Diffusion Models 該文提出一種基于文本的真實圖像編輯方法&#xff0c;能夠根據純文本提示&#xff0c;實現復雜的圖像編輯任務&#xff0c;如改變一個或多個物體的位姿和組成&#xff0c;并且保持其他特征不變。相比于其他文…

c語言題庫之序列合并

文章目錄 前言C語言題目&#xff1a;分析1. 合并邏輯2.圖解合并邏輯 代碼實現注意事項總結思考 前言 在編程中&#xff0c;我們經常遇到需要將兩個有序序列合并為一個有序序列的問題。下面&#xff0c;我們就來詳細探討一下如何解決這個問題&#xff0c;包括輸入處理、合并邏輯…

python 根據網址和關鍵詞批量下載影像

最近用到了GLASS的LAI產品&#xff0c;但這個產品的文件夾分得很細&#xff0c;我需要的影像又有8個瓦片&#xff0c;一個一個點擊很麻煩&#xff0c;于是探索了批量下載的方法 一、下載1幅 import requests import re import os import requests import re# 網頁URLurl &…

深入理解Java HashSet類及其實現原理

哈嘍&#xff0c;各位小伙伴們&#xff0c;你們好呀&#xff0c;我是喵手。運營社區&#xff1a;C站/掘金/騰訊云&#xff1b;歡迎大家常來逛逛 今天我要給大家分享一些自己日常學習到的一些知識點&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相學習&#xff0c;一…

Java中什么是多態?多態的實現原理是什么?多態在Java中的意思實現方式是什么?多態在框架設計中有什么作用應用場景?

什么是多態&#xff1f; 多態是面向對象編程中的一個重要概念&#xff0c;它允許不同類的對象對同一消息做出響應。在 Java中&#xff0c;多態通常體現為子類對象可以替代父類對象的特性。這意味著你可以使用父類的引用來引用子類的對象。 多態的實現原理&#xff1a; 多態的…

如何在 CentOS 上安裝并配置 Redis

如何在 CentOS 上安裝并配置 Redis 但是太陽&#xff0c;他每時每刻都是夕陽也都是旭日。當他熄滅著走下山去收盡蒼涼殘照之際&#xff0c;正是他在另一面燃燒著爬上山巔散烈烈朝暉之時。 ——史鐵生 環境準備 本教程將在 CentOS 7 或 CentOS 8 上進行。確保你的系統已更新到最…

Channel實現Flutter與原生平臺之間的雙向通信

文章目錄 &#xff08;一&#xff09;通過MessageChannel實現Flutter與原生平臺之間的雙向通信Flutter端實現MessageChannel通信步驟&#xff1a;Android端實現MessageChannel通信步驟&#xff1a; &#xff08;二&#xff09;通過MethodChannel實現Flutter與原生平臺之間的雙向…

uniapp/微信小程序實現加入購物車點擊添加飛到購物車動畫

1、預期效果 2、實現思路 每次點擊添加按鈕時&#xff0c;往該按鈕上方添加一個懸浮元素&#xff0c;通過位移動畫將元素移到目標位置。 1. 為每個點擊元素設置不同的class&#xff0c;才能通過uni.createSelectorQuery來獲取每個元素的節點信息&#xff1b; 2. 添加一個與…

c++:(map和set的底層簡單版本,紅黑樹和AVL樹的基礎) 二叉搜索樹(BST)底層和模擬實現

文章目錄 二叉搜索樹的概念二叉搜索樹的操作二叉搜索樹的查找find 二叉搜索樹的模擬實現構造節點insertfinderase(細節巨多,面試可能會考)a.葉子節點b.有一個孩子左孩子右孩子 c.有兩個孩子注意: erase代碼 中序遍歷 二叉搜索樹的應用k模型k模型模擬實現的總代碼 k-value模型k-…

7-Zip命令行調用命令收集(20個)

列出壓縮文件的內容: 7z l archive.7z 解壓壓縮文件到當前目錄: 7z x archive.7z 解壓壓縮文件到指定目錄: 7z x archive.7z -o"C:\path\to\extract" 創建新的壓縮文件 (添加到archive.7z): 7z a archive.7z file_to_compress 創建包含多個文件的壓縮文件: 7z a arc…

【JVM】了解JVM規范中的虛擬機結構

目錄 JVM規范的主要內容 1&#xff09;字節碼指令集(相當于中央處理器CPU) JVM指令分類 2&#xff09;Class文件的格式 3&#xff09;數據類型和值 4&#xff09;運行時數據區 5&#xff09;棧幀 6&#xff09;特殊方法 7&#xff09;類庫 JVM規范的主要內容 1&#…

Vue3+ElementPlus+TS開發業務功能的問題匯總(持續更新)

1.開發表單彈框功能時遇到兩個問題&#xff1a;加入了校驗規則后&#xff0c;無論下拉框是否選擇數據下面的紅色提示都會觸發顯示不會自動隱藏 &#xff1b; 另外&#xff0c;新增的功能在提交后數據無法重置&#xff0c;這種在修改時可能會出現&#xff0c;但新增正常情況是不…

走進C++:C到C++的過渡

目錄 什么是C呢&#xff1f; C的發展史 多了一些吃前來很香的“語法糖”。 語法糖一&#xff1a;命名空間 命名空間有個強大的功能 如何使用 語法糖二&#xff1a;缺省參數 語法糖三&#xff1a;函數重載 語法糖四&#xff1a;引用 引用傳參 引用返回 引用和…

【ZZULIOJ】1100: 求組合數(函數專題)(Java)

目錄 題目描述 輸入 輸出 樣例輸入 Copy 樣例輸出 Copy 提示 code 題目描述 馬上要舉辦新生程序設計競賽了&#xff0c;與以往不同的是&#xff0c;本次比賽以班為單位&#xff0c;為了全面衡量一個班級的整體水平&#xff0c;要求從一個班的m位同學中任選k位同學代表本…

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer與fence機制(2)

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer與fence機制&#xff08;2&#xff09; 計算fps幀率 用 adb shell dumpsys SurfaceFlinger --list 查詢當前的SurfaceView&#xff0c;然后有好多行&#xff0c;再把要查詢的行內容完整的傳給 ad…

算法訓練Day35 | ● 343. 整數拆分 ● 96.不同的二叉搜索樹

343. 整數拆分 class Solution { public:int integerBreak(int n) {vector<int> dp(n1, 0);dp[2] 1;for(int i3; i<n1; i){for(int j 1; j<i/2; j){dp[i] max(dp[i], max(j*(i-j), j*dp[i-j]));}}return dp[n];} };參考文章&#xff1a;代碼隨想錄-343. 整數拆分…

找不到msvcp140.dll無法執行代碼的原因分析及修復方法

當用戶在嘗試運行某些應用程序或游戲時&#xff0c;可能會遇到系統彈出錯誤提示&#xff0c;顯示“找不到msvcp140.dll無法執行代碼”這一錯誤信息&#xff0c;它會導致程序無法正常啟動。為了解決這個問題&#xff0c;我經過多次嘗試和總結&#xff0c;找到了以下五種解決方法…

hadoop啟動后沒有namenode,datanode等解決方法

之前用的是虛擬機&#xff0c;在虛擬機上安裝的hadoop&#xff0c;但是后來&#xff0c;電腦恢復出廠設置了&#xff0c;什么都重新開始。就在本地安裝 Linux 子系統。 但是&#xff0c;有時候start-dfs.sh后&#xff0c;jps出現錯誤。 像這種拒絕連接 解決辦法就是如下&…