国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

進程程序替換+簡易版shell實現(xiàn)

這篇具有很好參考價值的文章主要介紹了進程程序替換+簡易版shell實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

進程程序替換

什么是進程程序替換?
指在一個正在運行的進程中,將原來的程序替換成新的程序的過程。
eg:如果我們想讓fork創(chuàng)建出來的子進程執(zhí)行全新的任務,此時就需要進程程序替換
為什么要進程程序替換呢?
我們一般在服務器設計的時候(linux編程的時候)往往需要子進程干兩種事情

  1. 讓子進程執(zhí)行父進程的代碼片段(服務器代碼)
  2. 讓子進程執(zhí)行磁盤中的一個全新的程序,eg:通過我們的進程執(zhí)行其他人寫的進程代碼等等,可以使得我們的c/c++代碼調(diào)用c/c++/Python/Shell/Java等代碼

進程程序替換的原理
進程程序替換+簡易版shell實現(xiàn)
假設此時父進程執(zhí)行的是a.exe,fork創(chuàng)建子進程之后,原本子進程要繼承父進程的代碼和數(shù)據(jù),頁表等映射也都是一樣的,此時將磁盤中的b.exe加載如內(nèi)存結構,使得子進程重新建立頁表的映射關系,誰執(zhí)行程序替換就重新建立誰的映射(此時是子進程)
效果:此時做到了讓父子進程分離,并且讓子進程執(zhí)行一個全新的程序,至于如何做到,是有OS系統(tǒng)中的系統(tǒng)調(diào)用接口完成的。

如何進行程序替換

替換函數(shù)一共有六種,先用 execl第一種函數(shù)舉例子
進程程序替換+簡易版shell實現(xiàn)
我們要執(zhí)行一個全新的程序,需要做如下幾件事情

  1. 先找到這個程序在哪里
  2. 程序可能攜帶選項進行執(zhí)行,也可以不攜帶,(也就是程序怎么執(zhí)行的)我們需要明確告訴OS,我想怎么執(zhí)行這個程序,要不要帶選項
  3. eg:命令行怎么寫ls -l -a 第二個參數(shù)就怎么填 “l(fā)s”, “-l”, "-a"并且參數(shù)的最后一定是NULL,表示【如何執(zhí)行程序】參數(shù)傳遞完畢
    進程程序替換+簡易版shell實現(xiàn)

發(fā)現(xiàn)此時執(zhí)行了第一個printf,然后執(zhí)行了ls命令,但是第二個printf沒有打印了,為什么?
一旦替換成功,是將當前進程的代碼和數(shù)據(jù)全部替換,后面的printf是原來進程的代碼,所以改代碼早就被替換了,改代碼不存在了。
所以該程序替換函數(shù)需要返回值嗎?
int ret = execl(…)
一旦替換成功,就會執(zhí)行新的進程代碼,就不會有返回值
而失敗的話,必然會順著原來的進程代碼執(zhí)行,最多通過返回值得到是什么原因?qū)е碌奶鎿Q失?。?/p>

引入子進程創(chuàng)建
子進程執(zhí)行程序替換,會影響父進程嗎?
不會,因為進程具有獨立性
如何做到的?
數(shù)據(jù)層面發(fā)生寫實拷貝,程序替換的時候,我們可以理解為,代碼和數(shù)據(jù)都發(fā)生了寫實拷貝完成父子的分離。

19   printf("我是父進程,我的PID是:%d\n",getpid());
 20   pid_t id = fork();
 21   if(id == 0) {
 22     //我們想讓子進程執(zhí)行全新的程序,以前是執(zhí)行父進程的代碼片段
 23     printf("我是子進程,我的PID是:%d\n", getpid());
 24     execl("/usr/bin/ls","ls","-a","-l",NULL);
 25     printf("子進程替換進程失敗\n");
 26     exit(1);//只要執(zhí)行了exit,意味著,execl系列的函數(shù)失敗了
 27 
 28   }
 29   //一定是父進程                                                                                                                            
 30   int status = 0;
 31   printf("我是父進程,我的PID: %d,我準備等子進程啦!\n",getpid());
 32   int ret = waitpid(id,&status,0);//阻塞式等待子進程
 33   if(ret == id) {
 34     sleep(1);
 35     printf("父進程等待成功!子進程的退出碼是: %d  \n",(status>>8)&0XFF);
 36   }
 37   return 0;
 38 }

進程程序替換+簡易版shell實現(xiàn)

不同程序替換函數(shù)之間的區(qū)別

int execl(const char *path, const char *arg, …);
int execv(const char *path, char *const argv[]);
execv VS execl
二者幾乎是一樣的,只有傳參方式的區(qū)別,execl傳參的方式是list列表傳參,execv是vector數(shù)組傳參

進程程序替換+簡易版shell實現(xiàn)

int execvp(const char *file, char *const argv[]);
函數(shù)名中有p和v表示使用該函數(shù)時,可以不帶路徑,并且函數(shù)第二個參數(shù)傳參的時候是vector傳參

系統(tǒng)接口調(diào)用其他語言的函數(shù)

調(diào)用c++函數(shù)
進程程序替換+簡易版shell實現(xiàn)

調(diào)用Python

進程程序替換+簡易版shell實現(xiàn)

替換函數(shù)execle

int execle(const char *path, const char *arg, …,char *const envp[]);
函數(shù)名中的e表示環(huán)境變量
第三個參數(shù)既可以自己傳自定義的環(huán)境變量
也可以傳系統(tǒng)定義的環(huán)境變量,二者有所區(qū)分

進程程序替換+簡易版shell實現(xiàn)
上述代碼中:mycomd.cc調(diào)用了getenv函數(shù),打印出環(huán)境變量,而我們在mtproc.cc中先用execl調(diào)用mycomd,發(fā)現(xiàn)此時只有環(huán)境變量PATH那一行代碼被打印出來了,到MYPATH這行代碼時,就無法再運行下去了,因為此時在系統(tǒng)中沒有環(huán)境變量MYPATH。
進程程序替換+簡易版shell實現(xiàn)
如圖所示,如果我們導出環(huán)境變量變量的話,此時發(fā)現(xiàn)都可以打印出來了。
但是如果我們用execle函數(shù)自定義導入環(huán)境變量的話。

進程程序替換+簡易版shell實現(xiàn)
如果此時導入自定義變量,發(fā)現(xiàn)PATH系統(tǒng)自帶的環(huán)境變量打印不出,說明添加環(huán)境變量給目標進程,是覆蓋式的,只要傳入自定義的環(huán)境變量,那么原來的環(huán)境變量,就失去作用了。
進程程序替換+簡易版shell實現(xiàn)
進程程序替換+簡易版shell實現(xiàn)
如果execle傳入的是系統(tǒng)定義的環(huán)境變量,那么我們export導入的環(huán)境變量還是有用的。

問題:為什么程序替換會有那么多借口?
為了適配更多的應用場景
execve為什么是單獨的?

int execve(const char *path, char *const argv[], char *const envp[]);
只有這個函數(shù)是系統(tǒng)接口,上面的函數(shù)都是對這個函數(shù)的封裝
總結:
對于替換函數(shù)

l(list) : 表示參數(shù)采用列表
v(vector) : 參數(shù)用數(shù)組
p(path) : 有p自動搜索環(huán)境變量PATH
e(env) : 表示自己維護環(huán)境變量

簡易版shell實現(xiàn)

shell的大致原理,以ls為例
shell從用戶讀入字符串,shell建立一個新的進程,然后在那個進程中運行l(wèi)s程序并等待ls進程結束,然后shell讀取新的一行輸入,建立一個新進程,在這個進程中運行程序,并等待這個進程結束。所以要寫一個shell,需要循環(huán)以下過程:文章來源地址http://www.zghlxwxcb.cn/news/detail-448697.html

  1. 獲取命令行
  2. 解析命令行
  3. 建立一個子進程
  4. 替換子進程
  5. 父進程等待子進程退出
    僅僅支持一些簡單的命令
1 #include<stdio.h>
    2 #include<string.h>
    3 #include<stdlib.h>
    4 #include<unistd.h>
    5 #include<sys/types.h>
    6 #include<sys/wait.h>
    7 
    8 #define SEP " "
    9 #define NUM 1024
   10 #define SIZE 128
   11 char command_line[NUM];
   12 char *command_args[SIZE];
   13 char env_buffer[NUM];//fou test 
   14 extern char*enviorn;
   15 
   16 int ChangDir(const char * new_path)
   17 {
   18   chdir(new_path);
   19   return 0;//成功
   20 
   21 }
   22 void putEnvInMyShell(char *new_env)                                                                                                       
   23 {
   24   putenv(new_env);//此時是新增環(huán)境變量不是覆蓋
   25 }
   26 int main()
   27 {
   28   //shell本質(zhì)上就是一個死循環(huán)
   29   while(1)
   30   {
   31     //1.顯示提示符
   32     printf("[zjt@大帥比 當前目錄]# ");
   33     fflush(stdout);//強制刷新屏幕,否則上述信息回儲存在緩沖區(qū)中
   34     //2.獲取用戶輸入
   35     memset(command_line,'\0',sizeof(command_line)*sizeof(char));
   36     fgets(command_line,NUM,stdin);//鍵盤,標準輸入,stdin,獲取的是c風格的字符串,'\0';
   37     command_line[strlen(command_line)-1] = '\0';//清空'\n'
   38     //3."ls -a -l -i" -> "ls" "-a" "-l" "-i"字符串切分
   39     command_args[0] = strtok(command_line,SEP);
   40     int index = 1;
   41     //給ls命令添加顏色
   42     if(strcmp(command_args[0]/*程序名*/,"ls") == 0)
   43       command_args[index++] = (char*)"--color=auto";
   44     //strtok截取成功,返回字符串起始地址
   45     //截取失敗,返回NULL;
   46     while(command_args[index++] = strtok(NULL,SEP));
   47     //按照SEP進行字符串切割,第一次調(diào)用時,第一個參數(shù)指向要分割的字符串
   48     //以后每次調(diào)用第一個參數(shù)都指向NULL,表示繼續(xù)分割上一次的剩余部分
   49     //最終根據(jù)分割字符分割字符串
   50     //TODO,編寫后面的邏輯,內(nèi)建命令
   51     if(strcmp(command_args[0], "cd") == 0 && command_args[1] != NULL)
   52     {
   53       ChangDir(command_args[1]);//讓調(diào)用方進行路徑切換,父進程
   54       continue;                                                                                                                           
   55 
   56     }
   57     if(strcmp(command_args[0], "export") == 0 && command_args[1] != NULL)
   58     {
   59       //目前,環(huán)境變量信息在command_line,會被清空
   60       //此處我們需要保存一下環(huán)境變量內(nèi)容
   61       strcpy(env_buffer,command_args[1]);
   62       putEnvInMyShell(env_buffer);
   63       continue;
   64 
   65     }
   66     //5.創(chuàng)建進程,執(zhí)行
   67     pid_t id = fork();
   68     if(id == 0)
   69     {
   70       //child
   71       //6.程序替換
   72       execvp(command_args[0],/*我們保存的要執(zhí)行的程序名*/command_args);
   73       exit(1);
   74       //此時子進程調(diào)用一定失敗
   75     }                                                                                                                                     
   76     int status = 0;
W> 77     pid_t ret = waitpid(id, &status, 0);
   78   //  if(ret > 0)
   79   //  {
   80   //    printf("子進程等待成功,進程退出碼為:%d,退出信號為:%d\n",(status>>8)&0xFF,status&0xFF);
   81   //    
   82   //  }
   83   }
   84 }

到了這里,關于進程程序替換+簡易版shell實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【Linux初階】進程替換的應用 - 簡易命令行解釋器的實現(xiàn)

    【Linux初階】進程替換的應用 - 簡易命令行解釋器的實現(xiàn)

    ??hello,各位讀者大大們你們好呀?? ????系列專欄:【Linux初階】 ????本篇內(nèi)容:使用代碼手段實現(xiàn)一個簡易的命令行解釋器,其中功能包括:打印輸出提示符、獲取用戶輸入、字符串切割、執(zhí)行命令、ls指令下?lián)碛蓄伾崾尽d、echo; ????作者簡介:計算機海洋的

    2024年02月07日
    瀏覽(93)
  • 『Linux從入門到精通』第 ? 期 - 學會了程序替換,我決定手寫一個簡易版shell玩一玩...

    『Linux從入門到精通』第 ? 期 - 學會了程序替換,我決定手寫一個簡易版shell玩一玩...

    ??作者簡介: 花想云 ,在讀本科生一枚,C/C++領域新星創(chuàng)作者,新星計劃導師,阿里云專家博主,CSDN內(nèi)容合伙人…致力于 C/C++、Linux 學習。 ?? 專欄簡介:本文收錄于 Linux從入門到精通 ,本專欄主要內(nèi)容為本專欄主要內(nèi)容為Linux的系統(tǒng)性學習,專為小白打造的文章專欄。

    2024年02月14日
    瀏覽(18)
  • 【linux】進程替換的應用|shell解釋器的實現(xiàn)

    【linux】進程替換的應用|shell解釋器的實現(xiàn)

    當我們學過了進程替換之后,本篇文章可以根據(jù)進程替換的知識帶你自主實現(xiàn)一個shell命令行 實現(xiàn)步驟 1.顯示命令行提示 2.讀取輸入指令以及對應選項 3.分割第二步的指令以及選項到命令行參數(shù)表中 4.處理內(nèi)建命令 5.進程替換 我們通過觀察bash的命令行提示發(fā)現(xiàn)他是由三部分

    2024年04月26日
    瀏覽(100)
  • 【Linux】Linux進程控制 --- 進程創(chuàng)建、終止、等待、替換、shell派生子進程的理解…

    【Linux】Linux進程控制 --- 進程創(chuàng)建、終止、等待、替換、shell派生子進程的理解…

    柴犬: 你好啊,屏幕前的大帥哥or大美女,和我一起享受美好的今天叭?????? 1. 在調(diào)用fork函數(shù)之后, 當執(zhí)行的程序代碼轉(zhuǎn)移到內(nèi)核中的fork代碼后 ,內(nèi)核需要分配 新的內(nèi)存塊 和 內(nèi)核數(shù)據(jù)結構 給子進程, 內(nèi)核數(shù)據(jù)結構包括PCB、mm_struct和頁表,然后構建起映射關系 ,同時

    2024年01月16日
    瀏覽(25)
  • 【Linux】教你用進程替換制作一個簡單的Shell解釋器

    【Linux】教你用進程替換制作一個簡單的Shell解釋器

    本章的代碼可以訪問這里獲取。 由于程序代碼是一體的,本章在分開講解各部分的實現(xiàn)時,代碼可能有些跳躍,建議在講解各部分實現(xiàn)后看一下源代碼方便理解程序。 我們想要制作一個簡單的 Shell 解釋器,需要先觀察Shell是怎么運行的,根據(jù) Shell 的運行狀態(tài)我們再去進行模

    2024年02月02日
    瀏覽(112)
  • 【Linux】進程等待和替換——進程等待的原理、wait/waitpid方法、進程程序替換、進程替換原理、替換函數(shù)

    【Linux】進程等待和替換——進程等待的原理、wait/waitpid方法、進程程序替換、進程替換原理、替換函數(shù)

    1.1進程等待的概念 ?? 進程等待指的是父進程等待子進程退出,以獲取子進程的退出返回值,并釋放子進程占用的資源。 ?? 當子進程先于父進程退出,但父進程沒有關注子進程的退出狀態(tài)時, 子進程會為了保存自己的退出狀態(tài)而保持資源占用, 這種情況被稱為“僵尸進

    2024年02月04日
    瀏覽(18)
  • Linux進程控制【進程程序替換】

    Linux進程控制【進程程序替換】

    ?個人主頁: Yohifo ??所屬專欄: Linux學習之旅 ??每篇一句: 圖片來源 ??操作環(huán)境: CentOS 7.6 阿里云遠程服務器 Good judgment comes from experience, and a lot of that comes from bad judgment. 好的判斷力來自經(jīng)驗,其中很多來自糟糕的判斷力。 子進程 在被創(chuàng)建后,共享的是 父進程 的代碼

    2024年01月17日
    瀏覽(28)
  • [Linux 進程控制(二)] 進程程序替換

    [Linux 進程控制(二)] 進程程序替換

    首先,我們要認識到,我們之前fork()所創(chuàng)建的子進程,執(zhí)行的代碼,都是父進程的一部分(用if-else分流或者執(zhí)行同樣的代碼)! 如果我們想讓子進程執(zhí)行新的程序呢? 執(zhí)行全新的代碼和訪問全新的數(shù)據(jù),不再和父進程有瓜葛,這種技術就叫做程序替換 ,下面我們就來學習一

    2024年03月14日
    瀏覽(32)
  • Linux--進程控制(2)--進程的程序替換(奪舍)

    Linux--進程控制(2)--進程的程序替換(奪舍)

    目錄 進程的程序替換 0.相關函數(shù) 1.先看現(xiàn)象 ?2.解釋原理 3.將代碼改成多進程版 ?4.使用其它的替換函數(shù),并且認識函數(shù)參數(shù)的含義 5.其它 ?關于進程替換我們需要了解的6個函數(shù): 函數(shù)解釋: 這些函數(shù)如果調(diào)用成功則加載新的程序從啟動代碼開始執(zhí)行,不再返回。 如果調(diào)用出

    2024年04月29日
    瀏覽(23)
  • Linux :進程的程序替換

    Linux :進程的程序替換

    目錄 一、什么是程序替換 1.1程序替換的原理 1.2更改為多進程版本 二、各種exe接口 2.2execlp ??編輯 2.2execv 2.3execle、execve、execvpe 用fork創(chuàng)建子進程后執(zhí)行的是和父進程相同的程序(但有可能執(zhí)行不同的代碼分支),子進程往往要調(diào)用一種exec函數(shù)以執(zhí)行另一個程序。當進程調(diào)用一種

    2024年04月10日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包