当前位置: 首页 > news >正文

南京做网站xjrkj二手车网站系统

南京做网站xjrkj,二手车网站系统,京东可以免费做特效的网站,做微网站需要哪种公众号✅1主页#xff1a;#xff1a;我的代码爱吃辣 #x1f4c3;2知识讲解#xff1a;Linux——进程替换 ☂️3开发环境#xff1a;Centos7 #x1f4ac;4前言#xff1a;我们创建子进程的目的是什么#xff1f;想让子进程帮我们执行特定的… ✅1主页我的代码爱吃辣 2知识讲解Linux——进程替换 ☂️3开发环境Centos7 4前言我们创建子进程的目的是什么想让子进程帮我们执行特定的任务。那么如何让子进程去执行一段新的代码呢 一.背景 二.子进程程序替换 三.替换函数 1.execv 2.execlp 3.execle 4.命名理解 四.实现minishell 一.背景 我们创建子进程的目的是什么想让子进程帮我们执行特定的任务。 1.让子进程执行父进程的一部分代码 2.如果子进程指向一个全新的代码呢这就是进程的程序替换。 见一见单进程版本进程替换即父进程指向一个全新的代码: 隆重介绍一个接口 int execl(const char *path, const char *arg, ...); path替换程序的路径。arg如何执行该程序。可变参数如何执行该程序的参数等。 测试代码 #include stdio.h #include unistd.hint main() {printf(--------------------begin-------------\n);execl(/usr/bin/ls, ls, -a, -l, NULL);printf(--------------------end---------------\n);return 0; } 注意 我们想替换的程序 ls -a -l。ls 的路径:/usr/bin/ls。-a -l 时ls命令的参数。最后结束要以NULL结尾。 测试结果 注意 进程替换以后我们并没有看到我们源代码里面的最后一个打印。原因是程序在替换以后在后续执行完ls的代码就会退出了不会回到execl调用后面。 二.子进程程序替换 创建好子进程让子进程调用execl让子进程去执行替换的程序。 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。 测试代码 #include stdio.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {int status;printf(--------------------begin-------------\n);pid_t pid fork();if (pid 0){// 我们想替换的程序 ls -a -l// ls 的路径:/usr/bin/ls//-a -l 时ls命令的参数// 最后结束要以NULL结尾execl(/usr/bin/ls, ls, -a, -l, NULL);}waitpid(-1, status, 0);//阻塞等待子进程退出。if (WIFEXITED(status))printf(子进程退出,退出码:%d\n, WEXITSTATUS(status));elseprintf(子进程异常,收到信号%d\n, status 0x7F);printf(--------------------end---------------\n);return 0; } 测试结果 进程替换原理 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。 三.替换函数 其实有六种以exec开头的函数,统称exec函数: #include unistd.hint 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 execve(const char *path, char *const argv[], char *const envp[]); 函数解释 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。如果调用出错则返回-1。所以exec函数只有出错的返回值而没有成功的返回值。 介绍其中几个 1.execv int execv(const char *path, char *const argv[]); path:程序所在的路径argv是一个指针数组数组每一个元素代表我们需要怎么执行程序。 测试代码 #include stdio.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {int status;printf(--------------------begin-------------\n);pid_t pid fork();if (pid 0){// 我们想替换的程序 ls -a -l// ls 的路径:/usr/bin/ls//-a -l 时ls命令的参数// 最后结束要以NULL结尾char *argv[] {ls, -a, -l, NULL};execv(/usr/bin/ls, argv);}waitpid(-1, status, 0);if (WIFEXITED(status))printf(子进程退出,退出码:%d\n, WEXITSTATUS(status));elseprintf(子进程异常,收到信号%d\n, status 0x7F);printf(--------------------end---------------\n);return 0; } 测试结果 2.execlp int execlp(const char *file, const char *arg, ...); file:程序名称。后续参数需要怎么执行程序。不需要给出程序路径execlp会自己到环境变量中找对应的程序。 测试代码 #include stdio.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {int status;printf(--------------------begin-------------\n);pid_t pid fork();if (pid 0){// 我们想替换的程序 ls -a -l// ls 的路径:/usr/bin/ls//-a -l 时ls命令的参数// 最后结束要以NULL结尾execlp(ls, ls, -a, -l, NULL);}waitpid(-1, status, 0);if (WIFEXITED(status))printf(子进程退出,退出码:%d\n, WEXITSTATUS(status));elseprintf(子进程异常,收到信号%d\n, status 0x7F);printf(--------------------end---------------\n);return 0; }测试结果 3.execle int execle(const char *path, const char *arg, ...,char *const envp[]); path:程序路径。envp:是一个指针数组用来传输环境变量。arg:我们如何执行程序。 测试代码 #include stdio.h #include unistd.h #include sys/types.h #include sys/wait.hint main() {extern char **environ;int status;printf(--------------------begin-------------\n);pid_t pid fork();if (pid 0){// 我们想替换的程序 ls -a -l// ls 的路径:/usr/bin/ls//-a -l 时ls命令的参数// 最后结束要以NULL结尾execle(./newdir/otherproc, otherproc, NULL, environ);}waitpid(-1, status, 0);if (WIFEXITED(status))printf(子进程退出,退出码:%d\n, WEXITSTATUS(status));elseprintf(子进程异常,收到信号%d\n, status 0x7F);printf(--------------------end---------------\n);return 0; } newdir/otherproc.cc #include iostream #include unistd.h #include stdlib.husing namespace std;int main() {cout hello world hello: getenv(hello) endl;cout hello world hello: getenv(hello) endl;cout hello world hello: getenv(hello) endl;return 0; } 测试结果 4.命名理解 这些函数原型看起来很容易混,但只要掌握了规律就很好记。 l(list) : 表示参数采用列表v(vector) : 参数用数组p(path) : 有p自动搜索环境变量PATHe(env) : 表示自己维护环境变量  exec调用总结 #include unistd.h int main() {char *const argv[] {ps, -ef, NULL};char *const envp[] {PATH/bin:/usr/bin, TERMconsole, NULL};execl(/bin/ps, ps, -ef, NULL);// 带p的可以使用环境变量PATH无需写全路径execlp(ps, ps, -ef, NULL);// 带e的需要自己组装环境变量execle(ps, ps, -ef, NULL, envp);execv(/bin/ps, argv);// 带p的可以使用环境变量PATH无需写全路径execvp(ps, argv);// 带e的需要自己组装环境变量execve(/bin/ps, argv, envp);exit(0); } 事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。 四.实现minishell 用下图的时间轴来表示事件的发生次序。其中时间从左向右。shell由标识为sh的方块代表它随着时间的流逝从左向右移动。shell从用户读入字符串ls。shell建立一个新的进程然后在那个进程中运行ls程序并等待那个进程结束。 然后shell读取新的一行输入建立一个新的进程在这个进程中运行程序 并等待这个进程结束。 所以要写一个shell需要循环以下过程: 1. 获取命令行 2. 解析命令行 3. 建立一个子进程fork 4. 替换子进程execvp 代码 #include stdio.h #include string.h #include stdlib.h #include unistd.h #include sys/types.h #include sys/wait.h #include assert.h#define SEP #define MAX 1024 #define MAX_SUB 64// 分割命令ls -a -l -- ls,-a -l void split(char buff[], char *subbuff[]) {assert(buff);assert(subbuff);int i 0;subbuff[i] strtok(buff, SEP);while (subbuff[i] strtok(NULL, SEP)) // 如果没有找到分割就会返回NULL; }// 代码测定打印命令 void debug(char *subbuff[]) {int i 0;while (subbuff[i]){printf(%s\n, subbuff[i]);} }// 显示环境变量 void showenv() {extern char **environ;for (int i 0; environ[i]; i){printf([%d]:%s\n, i, environ[i]);} }int main() {int status 0; // 退出码参数char myenv[32][512] {0}; // 用户自定义环境变量int index_env 0;int last_exit 0;while (1){char buff[MAX] {0}; // 存储命令行输入的命令字符串char *subbuff[MAX_SUB] {NULL};printf(wq[aliyum]$:);fflush(stdout);// 1.获得命令字符串fgets(buff, sizeof(buff), stdin);// 2.解析命令// ls -a -l\n\0,strlen9,index(\n)8,去除回车。buff[strlen(buff) - 1] \0;// 分割字符串split(buff, subbuff);// 处理内建命令// 注意cd,export,env,echo,等命令都是内建命令即这些命令不能创建子进程执行只能bash自己执行if (strcmp(subbuff[0], cd) 0){if (subbuff[1] ! NULL)chdir(subbuff[1]);continue;}else if (strcmp(subbuff[0], export) 0){if (subbuff[1] ! NULL){// 这里不能将subbuff[1]直接导入环境变量因为环境变量表存储的都是指针必须使用一个单独空间strcpy(myenv[index_env], subbuff[1]);putenv(myenv[index_env]);}continue;}else if (strcmp(subbuff[0], env) 0){showenv();continue;}else if (strcmp(subbuff[0], echo) 0){// echo $PATHif (subbuff[1][0] $){if (subbuff[1][1] ?) // echo $?//最近一次推出吗{printf(%d\n, last_exit);}else // 提取环境变量{// PATHchar *subenv subbuff[1] 1;char *get_env getenv(subenv);if (get_env ! NULL){printf(%s%s\n, subenv, get_env);}}}continue;}if (strcmp(subbuff[0], ls) 0){int comm_index 0;while (subbuff[comm_index]){comm_index;}// 增加高亮subbuff[comm_index] --colorauto;}// 3.创建子进程pid_t pid fork();assert(pid 0);if (pid 0) // 子进程{extern char **environ;// 4. 程序替换execve(subbuff[0], subbuff, environ);}// // 测试// debug(subbuff);waitpid(pid, status, 0);if (WIFEXITED(status)){// 子进程退出设置退出码last_exit WEXITSTATUS(status);}}return 0; }
http://www.huolong8.cn/news/235945/

相关文章:

  • 公司企业网站建设需要哪些网站布局怎么设计
  • 做统计图的网站js做的网站
  • 门户网站综合型门户郑州经济技术开发区属于什么区
  • 开发网站如何赚钱中宁企业网络推广联系人
  • 网站建设2018需要什么网站开发可选择的方案有哪些
  • html做的好看的网站一句话介绍网站开发
  • 苏中建设集团网站官网wordpress 根据权限获取用户信息
  • 网站建设制作费绵阳最有实力的公司网站建设
  • 山东安康建设项目管理有限公司网站石家庄网站建设q.479185700棒
  • 怎么制作网站视频汕头网站建设网站推广
  • 无障碍网站建设的摘要怎么定义自豪地采用WordPress
  • 购物网站技术实施方案友情链接怎么设置
  • 小说网站制作开源泾县网站seo优化排名
  • 贵阳网站维护培训2018十大网络营销案例
  • 企业网站设计论文摘要怎么写python网站和js做网站
  • 网站建设 推广 公司局域网 wordpress
  • 企业网站网页设计的步骤网站经常做封面的那些番号
  • 做网站 前途北京高端网站建设工作
  • 淘宝的网站建设方案网页设计实训报告题目来源
  • 公司内部 网站开发wordpress 局域网
  • 成都公司网页制作服务电话seo网址
  • 网站建设厘金手指排名二二长沙建设工程信息网
  • 网页图成都网站排名 生客seo怎么样
  • 广州网站改版腾讯企业邮箱注册申请
  • 上海p2p网站建设自建团队网站开发要多少钱
  • 用vs做购物网站代码wordpress google字体本地
  • 一个空间可以放两个网站吗网站制作优化推广
  • 学校的网站建设费如何入账管理网站开发教程
  • 爱站网站长seo综合查询工具设置网站语言
  • 南京网站设计是什么在浴室里做的网站