中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

金昌網(wǎng)站seo合肥seo推廣培訓(xùn)班

金昌網(wǎng)站seo,合肥seo推廣培訓(xùn)班,織夢網(wǎng)站后臺密碼忘記了怎么做,春節(jié)網(wǎng)頁設(shè)計素材網(wǎng)站Linux程序替換創(chuàng)建子進程的目的?程序替換如何實現(xiàn)程序替換?什么是程序替換?先見一見單進程版本的程序替換程序替換原理多進程版本的程序替換execl函數(shù)組簡易版Shell創(chuàng)建子進程的目的? 目的:為了幫助父進程完成一些特定的任務(wù)&…

Linux程序替換

  • 創(chuàng)建子進程的目的?
  • 程序替換
    • 如何實現(xiàn)程序替換?
    • 什么是程序替換?
      • 先見一見單進程版本的程序替換
      • 程序替換原理
    • 多進程版本的程序替換
  • execl函數(shù)組
  • 簡易版Shell

創(chuàng)建子進程的目的?

目的:為了幫助父進程完成一些特定的任務(wù);
子進程幫助父進程完成任務(wù)的方式有那些?
1、執(zhí)行一段父進程的代碼;(這是我們初學(xué)者經(jīng)常使用子進程的方式):
在這里插入圖片描述
2、讓子進程執(zhí)行一段與父進程完全不一樣、全新的代碼;
那么如何做到讓子進程執(zhí)行一段全新的代碼呢?
對子進程實現(xiàn)程序替換

程序替換

如何實現(xiàn)程序替換?

Linux給我們提供了7個接口:
#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[]);
這些函數(shù)叫做exec函數(shù)組,我們暫且先不詳細講解著些函數(shù)的具體用法,我們后文在重點講解;
我們現(xiàn)在只需知道通過調(diào)用這7個函數(shù)中的任意一個就可以完成程序替換;

什么是程序替換?

先見一見單進程版本的程序替換

為此我們先從最簡單的ececl()函數(shù)講解著走:
execl函數(shù)第一個參數(shù)path,表示我們要替換的程序在哪里,第二個參數(shù)arg表示我們想用怎么樣的方式運行我們的程序!寫完記得在傳個參數(shù)NULL結(jié)尾!
test代碼:
在這里插入圖片描述
運行結(jié)果如下:
在這里插入圖片描述
現(xiàn)象:我們觀察到了我們的進程執(zhí)行了我們begin的打印,然后又立馬執(zhí)行了ls -a -l命令,隨之整個進程就運行結(jié)束了,我們發(fā)現(xiàn)并沒有像我們想象的那樣接著運行我們所寫的printf(“end…\n”);語句;
這是為什么?
想要弄清楚這些現(xiàn)象產(chǎn)生的原因我們就必須清楚execl()接口進行程序替換的原理;

程序替換原理

首先根據(jù)上面的代碼,我們自己寫的代碼(比如:打印begin的語句)在運行起來的時候就已經(jīng)是一個進程,那么這時候該進程就已經(jīng)有了自己的內(nèi)核數(shù)據(jù)結(jié)構(gòu)了,比如:pcb、進程地址空間、頁表等!現(xiàn)在當(dāng)我們的進程運行到ececl語句的時候,會發(fā)生程序替換:
在這里插入圖片描述
當(dāng)我們自己寫的程序運行到execl()語句時,就會根據(jù)ececl()的path參數(shù),將ls命令從磁盤加載進物理內(nèi)存!加載到物理內(nèi)存的那個地方呢?加載到我們自己寫的程序?qū)?yīng)的物理內(nèi)存上的位置!
也就是說用ls命令的數(shù)據(jù)和代碼,替換原來老的程序的代碼和數(shù)據(jù),物理空間還是原來的物理空間,頁表的映射關(guān)系也基本不變,如果ls命令數(shù)據(jù)和代碼太多了,os會在頁表增加一些映射關(guān)系!然后該進程開始重新運行一段新的程序!
在這里插入圖片描述
明白了上面的原理,我們就能明白為什么我們的老程序在運行到execl過后,會執(zhí)行一段新的程序!同時由于新程序的代碼和數(shù)據(jù)替換了老程序的代碼和數(shù)據(jù),當(dāng)新程序運行結(jié)束過后,并不會再去運行原來老的程序的剩下的語句,比如上面代碼中的打印end語句,因為打印end語句屬于老程序的代碼,而老程序的代碼在execl接口中就被替換了,新程序運行完畢,也就表示這個進程終止了!新程序的退出碼也就是該進程的退出碼了!
換而言之,就是當(dāng)我們的程序利用execl完成程序替換過后,當(dāng)前進程的退出碼就由新程序決定了!
為此我們可以查看一下在程序替換過后,進程的退出碼!
測試代碼:
在這里插入圖片描述
在這里插入圖片描述
當(dāng)然我們也可以讓我們的程序執(zhí)行一個錯誤的ls命令,再次來觀察當(dāng)前進程的退出碼:
在這里插入圖片描述
在這里插入圖片描述
站在進程的角度的角度來看等待程序替換:
現(xiàn)在我是一個進程,我的代碼段和數(shù)據(jù)段都在物理內(nèi)存上有一份映射,現(xiàn)在我調(diào)用了execl接口,execl會將我在物理內(nèi)存上的數(shù)據(jù)和代碼用一個新的程序的數(shù)據(jù)和代碼來替換!然后我(當(dāng)前進程)開始重新運行這段新程序!并且我(當(dāng)前進程)的退出碼由這個新程序的main函數(shù)返回值來確定!在整個程序替換期間,我(當(dāng)前進程)并沒由被銷毀,我依舊存在!在完成程序替換過后,依舊是我(當(dāng)前進程)來運行這段新程序!并不會創(chuàng)建一個新的進程來運行新的代碼
站在新程序的角度來看待程序替換:
我是一個程序,我安安靜靜的躺在磁盤看“電視”,突然某一天我被execl加載進內(nèi)存,讓后某個進程就要求我?guī)退k件事;那么我(新程序)被加載進內(nèi)存這個動作是由誰完成的? execl!!!
execl就充當(dāng)著這個加載器的角色!
既然我自己寫的程序都能加載新的程序,那么OS?
當(dāng)我們想要運行某段程序的時候,OS會首先為我們的程序建立pcb、進程地址空間、頁表等內(nèi)核數(shù)據(jù)結(jié)構(gòu),也就是說這時候進程已經(jīng)創(chuàng)建好了,然后在讓當(dāng)前進程調(diào)用execl()接口將我們的程序加載進內(nèi)存,然后再開始運行我們程序!而我們的程序是從main函數(shù)開始的,但是我們的進程是先調(diào)用的execl過后我們的程序才開始運行起來的,那么換而言之在execl內(nèi)部,幫助我們完成程序替換過后,execl會調(diào)用該程序的main函數(shù),然后讓該程序成功運行起來!

多進程版本的程序替換

上面我們講解了單進程版本的程序替換和程序替換的原理,接下來我們來嘗試一下多進程版本的程序替換:
也就是說我們讓我們的子進程去執(zhí)行一段與父進程完全不一樣的代碼:
測試代碼:
在這里插入圖片描述
在這里插入圖片描述
當(dāng)然,我們也可以讓子進程去運行我們自己寫的程序,無論我們的程序是用什么語言寫的!
比如,現(xiàn)在我用C語言寫一個程序,去運行一個C++寫的程序:
測試:
被子進程運行的程序:
在這里插入圖片描述
主程序:
在這里插入圖片描述
運行結(jié)果:
在這里插入圖片描述

接下來我們來講解一下多進程進行程序替換的原理
首先我們的父進程,也就是mytest利用fork函數(shù)創(chuàng)建了一個子進程對吧!
那么剛開使的時候,子進程會繼承父進程的大多數(shù)信息,包括子進程會共享著父進程的代碼和數(shù)據(jù),通過前面的學(xué)習(xí)我們知道,當(dāng)我們的子進程想要修改與父進程共享的數(shù)據(jù)時,會發(fā)生寫時拷貝!在物理內(nèi)存中重新找一塊新空間,讓后將將需要修改的數(shù)據(jù)拷貝到新空間中去,然后修改子進程頁表映射到該物理內(nèi)存的映射關(guān)系,然后再讓子進程去修改數(shù)據(jù)!以此達到進程之間的相互獨立!
那么現(xiàn)在也是這樣:剛開始的時候父子進程都共享著同一塊物理內(nèi)存的數(shù)據(jù)和代碼:
在這里插入圖片描述
當(dāng)我們的子進程調(diào)用execl函數(shù)進行程序替換時,是會用程序的代碼和數(shù)據(jù)來替換子進程原來數(shù)據(jù)段和代碼段存的信息的!如果我們直接在“數(shù)據(jù)”和“代碼”這塊空間進行替換的話,我們就會將父進程的代碼和數(shù)據(jù)也替換掉!從而影響到了進程的獨立性!我們現(xiàn)在的目的是不想影想父進程,而讓子進程執(zhí)行一段全新的代碼,為此os也會也會觸發(fā)寫時拷貝,當(dāng)我們的子進程嘗試修改代碼段和數(shù)據(jù)段的信息時,os也會去重新找一物理內(nèi)存中重新找一塊空間來存儲子進程的代碼和數(shù)據(jù),同時修改子進程代碼段和數(shù)據(jù)段映射關(guān)系!
重新理解Shell運行原理
明白了上面的過程我們就能更好的理解Shell的運行原理了,首先shell從命令行接受到我們的命令后會創(chuàng)建一個子進程來執(zhí)行我們的命令,然后在讓該子進程調(diào)用execl函數(shù)來進程程序替換,替換掉子進程從Shell哪里繼承下來的代碼和數(shù)據(jù)!然后讓子進程開始運行這段程序!

execl函數(shù)組

下面我們來正式介紹一下execl函數(shù)組:
int execl(const char *path, const char *arg, …)
參數(shù): path//用于指定我們執(zhí)行的命令在哪里
arg: 可變參數(shù),可以傳任意個參數(shù),該參數(shù)的作用主要是告訴execl()你想怎樣執(zhí)行這段程序,你在命令行是怎么寫的,在arg參數(shù)就怎么寫,注意分割;比如:我們需要讓execl按照ls -a -l的格式執(zhí)行l(wèi)s命令,那么我們喂給execl的參數(shù)就是(從第二個參數(shù)起):“l(fā)s”、“-a”、“-l”,NULL;一個選項一個字符串,注意當(dāng)我們確定完程序運行的格式過后,必須以再傳遞一個NULL結(jié)尾!表示我們已經(jīng)傳遞完當(dāng)前程序的執(zhí)行的格式;
比如:
在這里插入圖片描述
返回值:該函數(shù)只會返回-1;由于execl是進行程序替換,當(dāng)execl完成程序替換那一刻開始,execl后續(xù)的代碼都被替換成了新程序的代碼和數(shù)據(jù),根本就運行不到后續(xù)的代碼和數(shù)據(jù),因此也就無法返回程序替換成功的返回值;當(dāng)我們的程序替換失敗的時候,我們進程的老數(shù)據(jù)和代碼并沒由被替換掉,當(dāng)前進程依舊按照順序執(zhí)行剩下的代碼,同時才能向上面返回-1來表示程序替換失敗!
也就是說,execl程序替換成功是沒有返回值的!如果execl有返回值那么說明程序替換失敗,當(dāng)前進程就會執(zhí)行execl后續(xù)的代碼!
int execv(const char *path, char *const argv[]);
我們可以發(fā)現(xiàn)execv接口與execl接口十分相似,但是在參數(shù)上卻并不是一樣的!
execl的參數(shù)可以是任意個,而execv的參數(shù)只有2個;
同時execv的功能與execl的功能一樣,只是在使用上有點區(qū)別!
我們可以看一看exec+l就表示execl,這個l(list)就代表著列表的意思!表示execl的程序運行格式以列表的形式傳遞!
exec+v表示execv,這個v(vector)表示數(shù)組的意思,就表示程序運行的格式以數(shù)組的形式傳遞;
具體演示:
在這里插入圖片描述
程序運行結(jié)果:
在這里插入圖片描述
程序依舊正常運行;
有了前面的理解后面我們在認識其他exec函數(shù)就輕松了:
int execlp(const char *file, const char *arg, …);
exec+l+p:l表示以列表的形式傳遞程序如何運行這個程序!
p:表示path,表示我們只需告訴execlp我們要運行的程序的名稱也就是傳遞file參數(shù),execlp會自動去PATH環(huán)境變量下搜索!
具體演示:
在這里插入圖片描述
程序運行結(jié)果:
在這里插入圖片描述
int execle(const char *path, const char *arg, …,char *const envp[]);
l:如何運行程序的參數(shù)以列表的形式傳遞;
e:env表示自己維護環(huán)境變量
比如:我們可以將當(dāng)前進程的環(huán)境變量表傳遞給我們的新程序!
我們的新程序就可以使用這張環(huán)境變量表:
子進程去替換的程序:
在這里插入圖片描述
主程序:
在這里插入圖片描述
程序運行結(jié)果:
在這里插入圖片描述
我們也可以向環(huán)境變量里面加一點東西進去:
這里我們就需要使用putenv()這個函數(shù)了,putenv()功能是向環(huán)境變量表中導(dǎo)入一個環(huán)境變量!
在這里插入圖片描述
在這里插入圖片描述
講解到這里,其他的execl函數(shù)也就依此類推了;

只不過我們需要注意一下,在exec函數(shù)組中
只有int execve(const char *filename, char *const argv[])是真正的系統(tǒng)調(diào)用!
其他的exec函數(shù)是基于該系統(tǒng)調(diào)用進行的封裝!

簡易版Shell

#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<stdbool.h>#define COMMOD_NUM 256
#define ARGV_NUM 64bool Strtok(char*commod,char**argv)
{//先跳過空格size_t i=0;size_t len=strlen(commod);size_t k=0;while(i<len&&commod[i]==' ')i++;if(i>=len)return false;size_t begin=i;size_t end=begin;while(begin<len){while(commod[end]!=' '&&commod[end]!='\0')end++;commod[end]='\0';argv[k++]=commod+begin;begin=end+1;end=begin;   }argv[k]=NULL;return true;
}
extern char**environ;
int main()
{while(1)
{printf("[cxk@VM-12-16-centos myshell]$ ");
char commod[COMMOD_NUM]={0};//用于接受從命令行輸入的命令
char*argv[ARGV_NUM]={NULL};//用于存儲將commod切割成一個一個字符串的指針
fgets(commod,COMMOD_NUM,stdin);
commod[strlen(commod)-1]='\0';//分割字符串if(Strtok(commod,argv)==false)continue;
//創(chuàng)建子進程
pid_t id=fork();
if(id==0)
{
int n= execvp(argv[0],argv);
if(n==-1)
{printf("-bash: %s: command not found\n",argv[0]);exit(1);
}
}
//父進程
waitpid(-1,NULL,0);
}return 0;
}
http://www.risenshineclean.com/news/48827.html

相關(guān)文章:

  • 蘇州專業(yè)做網(wǎng)站公司有哪些小說推廣關(guān)鍵詞怎么弄
  • 做網(wǎng)站需要的照片網(wǎng)站建設(shè)公司哪個好呀
  • 建站公司 萬維科技外鏈交換平臺
  • 網(wǎng)站設(shè)置密碼百度網(wǎng)站域名注冊
  • 給企業(yè)做宣傳網(wǎng)站的好處百度上如何發(fā)廣告
  • 開發(fā)平臺游戲名詞解釋搜索引擎優(yōu)化
  • 貴陽疫情最新消息今天寧波seo排名優(yōu)化培訓(xùn)
  • 網(wǎng)站建設(shè)公司信息搜索引擎營銷的優(yōu)勢和劣勢
  • 織夢的手機端網(wǎng)站模板技能培訓(xùn)有哪些科目
  • 破解版下載大全免費下載seo優(yōu)化軟件有哪些
  • 湛江免費建站哪里有淘寶聯(lián)盟怎么推廣
  • 鄭州網(wǎng)站開發(fā)設(shè)計公司電話個人如何優(yōu)化網(wǎng)站有哪些方法
  • 如何建立網(wǎng)站做微商企業(yè)網(wǎng)站模板 免費
  • 多語種網(wǎng)站建設(shè)手機版怎么用百度快照
  • 馬鞍山住房和城鄉(xiāng)建設(shè)局網(wǎng)站免費發(fā)帖論壇大全
  • 國內(nèi)ip地址代理免費信息流優(yōu)化師簡歷怎么寫
  • 建立網(wǎng)站站點的步驟技術(shù)培訓(xùn)平臺
  • 做電影網(wǎng)站服務(wù)器需求seo導(dǎo)航站
  • 給網(wǎng)站做接口企業(yè)培訓(xùn)考試系統(tǒng)
  • 廬江有做網(wǎng)站的嗎財經(jīng)新聞每日財經(jīng)報道
  • 連江網(wǎng)站建設(shè)服務(wù)index百度指數(shù)
  • 高德地圖有外資背景嗎優(yōu)化大師官方
  • 煙臺網(wǎng)站建設(shè).comseo自然搜索優(yōu)化排名
  • 網(wǎng)站域名過期怎么做重慶網(wǎng)站快速排名提升
  • 大上海小程序開發(fā)搜索引擎優(yōu)化的主題
  • 萬維網(wǎng)的網(wǎng)站抖音優(yōu)化排名
  • 南寧美麗南方官方網(wǎng)站建設(shè)意見企業(yè)網(wǎng)站建設(shè)的基本流程
  • 網(wǎng)站開通后百度廣告收費
  • 固始做網(wǎng)站網(wǎng)絡(luò)銷售哪個平臺最好
  • 幼兒園50個主題網(wǎng)絡(luò)圖關(guān)鍵詞優(yōu)化的作用