日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

进程程序替换

發(fā)布時(shí)間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 进程程序替换 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引入進(jìn)程程序替換的概念

一般在fork了一個(gè)子進(jìn)程之后,子進(jìn)程往往會(huì)調(diào)用exec函數(shù)組來(lái)執(zhí)行其他的程序,因?yàn)槲覀兊淖舆M(jìn)程不可能直接執(zhí)行很多的功能,這個(gè)大家在以后的操作中會(huì)慢慢的體會(huì)到

程序替換的幾個(gè)特點(diǎn)

  • 進(jìn)程在使用exec函數(shù)族進(jìn)程進(jìn)程替換的時(shí)候,并沒(méi)有創(chuàng)建一個(gè)新的進(jìn)程,所以當(dāng)前進(jìn)程的進(jìn)程ID并沒(méi)有改變。exec函數(shù)族只是用磁盤(pán)上面的一個(gè)新程序替換了當(dāng)前進(jìn)程的正文段、數(shù)據(jù)段、堆段和棧段。
  • 調(diào)用exec函數(shù)族后,除非調(diào)用失敗,否則沒(méi)有返回值,并且調(diào)用失敗之后,調(diào)用處之后的子進(jìn)程的程序繼續(xù)執(zhí)行,如果調(diào)用成功,調(diào)用處之后的子進(jìn)程將不再執(zhí)行。
  • 當(dāng)子進(jìn)程調(diào)用exec函數(shù)族之后,不管成功與否,父進(jìn)程依然可以正常執(zhí)行的。
    下面我們想寫(xiě)一些程序來(lái)測(cè)試上面的例子
#include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 int main()5 {6     pid_t son = fork();7     if(son == 0)  //子進(jìn)程8     {9         printf("i am son. my id is %d\n",getpid());10         execl("/bin/ls","ls","-a","-n","-l",NULL);11         printf("調(diào)用exec函數(shù)失敗\n");12         exit(0);13     }14     else //父進(jìn)程15     {16         printf("i am father\n");17         sleep(5);18     }19 20     return 0;21 }

這里的結(jié)果如下圖所示


我們來(lái)根據(jù)上面的結(jié)果來(lái)分析一下,這里執(zhí)行完我們的替換函數(shù)之后,就沒(méi)有執(zhí)行printf(“執(zhí)行完畢exec函數(shù)\n”);說(shuō)明 我們上文中的第二個(gè)結(jié)論中“如果調(diào)用成功調(diào)用處之后的子進(jìn)程將不再執(zhí)行”是正確的。
接下來(lái)我們把程序改一下,測(cè)試一下如果調(diào)用失敗是一個(gè)什么樣的結(jié)果
我們這里只把exec函數(shù)中的”/bin/ls”改成”/bin/lsss”這樣它在bin目錄下肯定是找不到了,所以程序應(yīng)該是調(diào)用失敗的,失敗了之后顯示的結(jié)果是下圖


這說(shuō)明當(dāng)我們exec函數(shù)失敗后,調(diào)用的進(jìn)程沒(méi)有被替換,所以后面的程序繼續(xù)執(zhí)行
然后我們還需要看一下父進(jìn)程的 結(jié)果是什么樣的,從 上面的結(jié)果看不管子子進(jìn)程調(diào)用exec函數(shù)結(jié)果如何,父進(jìn)程始終正常運(yùn)行。
接下來(lái)我們?cè)嚵艘幌聉fork的結(jié)果是什么樣的,測(cè)試之后的結(jié)果還是什么上面的結(jié)論,當(dāng)子進(jìn)程調(diào)用exec函數(shù)族之后,不管成功與否,父進(jìn)程依然可以正常執(zhí)行的
大家可以下去嘗試一下vfork,vfork的作用 是保證子進(jìn)程先執(zhí)行。

簡(jiǎn)析exec函數(shù)族

首先看一下exec函數(shù)族的定義

#include <unistd.h>2 extern char **environ;3 int execl(const char *path,const char *arg, ...);5 int execlp(const char *file, 6            const char *arg, ...);7 int execle(const char *path,8            const char *arg,9            ..., 
10            char * const envp[]);
11 int execv(const char *path,
12           char *const argv[]);
13 int execvp(const char *file, 
14            char *const argv[]);
15 int execve(const char *file,
16             char *const argv[],
17             char *const envp[]);

淺析進(jìn)程替換函數(shù)
進(jìn)程替換函數(shù)有六種分別是execl、execlp、execle和execv、execvp、execve,我們首先觀察這幾個(gè)函數(shù)會(huì)發(fā)現(xiàn)這些函數(shù)都是以exec開(kāi)頭的,由此我們稱(chēng)這些函數(shù)是exec函數(shù)族。
接下來(lái)又分為兩類(lèi),一類(lèi)是execl,一類(lèi)是execv。前面三個(gè)是以execl開(kāi)頭,這個(gè)開(kāi)頭有一個(gè)特點(diǎn)就是在exec后面加上了l,我們發(fā)揮想象 可以想象到STL中的list,就是一個(gè)鏈表,這里可以理解為我們?cè)谑褂眠@中類(lèi)型的函數(shù)的時(shí)候是需要傳入的一個(gè)可變的參數(shù)列表的。
這個(gè)可變參數(shù)列表實(shí)際上就是一些程序的一些可執(zhí)行選項(xiàng),比如我們?cè)趫?zhí)行l(wèi)s命令的時(shí)候,實(shí)際上就是在shell程序下進(jìn)行了一次程序替換,在執(zhí)行l(wèi)s的時(shí)候我們可以給他它加上許多選項(xiàng),比如ls -a -l等等。
另外就是execv,這個(gè)v可以讓我們想起STL中的vector,就是線性表,就是我們?cè)谑褂眠@個(gè)函數(shù)的時(shí)候需要傳入的是一個(gè)數(shù)組。

再來(lái)解釋一下帶有p的函數(shù),表示不需要加入替換程序的絕對(duì)路徑或者是相對(duì)路徑,不帶p的就是要加入絕對(duì)路徑或者是相對(duì)路徑,另外還有就是帶有e的函數(shù),這個(gè)時(shí)候我們可以傳入特定的環(huán)境變量。

接下來(lái)舉例子來(lái)具體看看這些函數(shù)是如何使用,比如我們?cè)诟高M(jìn)程中創(chuàng)建了一個(gè)子進(jìn)程,然后又在這個(gè)子進(jìn)程中的合適位置調(diào)用了exec函數(shù),那么這個(gè)時(shí)候就會(huì)發(fā)生程序替換

execl
execl("/bin/ls","ls","-a","-l","-n",NULL)

這里因?yàn)槭且粋€(gè)execl函數(shù),他沒(méi)有帶有p,所以我們第一個(gè)參數(shù)傳遞的是替換程序的絕對(duì)路徑或者是相對(duì)路徑,這里我門(mén)替換的函數(shù)是ls函數(shù),它的絕對(duì)路徑是”/bin/ls”,下面的那些事執(zhí)行這個(gè)程序的一些選項(xiàng),注意要以NULL結(jié)尾

execlp
execlp("ls","ls","-a","-l","-n",NULL)

加上這個(gè)p之后我們就不需要加上程序的路徑了,execlp會(huì)自己搜索,這個(gè)時(shí)候有人就會(huì)問(wèn)了,為什么還要寫(xiě)兩次ls呢,這里第一個(gè)ls是我們需要執(zhí)行的程序,第二個(gè)ls結(jié)合著后面的一些選項(xiàng)就是我們是要如何執(zhí)行。

execv
char* _agrv[] = {"ls","-a","-n","-l",NULL};
execv("/bin/ls",_agrv);

其實(shí)這里很簡(jiǎn)單,我們無(wú)非就是把上面的那個(gè)函數(shù)的后面的選項(xiàng)加入到一個(gè)指針數(shù)組里面去了,這個(gè)就是execv函數(shù)組的意義,其他的兩個(gè)函數(shù)這里就不解釋了。

execle

這個(gè)函數(shù)我們需要傳入特定的環(huán)境變量,這個(gè)留個(gè)懸念,大家自己網(wǎng)上搜索吧。
補(bǔ)充說(shuō)明,上面替換的程序可以是大家自己寫(xiě)的程序哦…

總結(jié)

以上是生活随笔為你收集整理的进程程序替换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。