IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 进程控制2 进程程序替换 -> 正文阅读

[C++知识库]进程控制2 进程程序替换

1.为啥需要进程程序替换

因为父进程创建出来的子进程和父进程拥有相同的代码段,所以,子进程的代码和父进程是一样的。当我们想要让子进程执行不同的程序时候,就需要让子进程调用进程程序替换的接口,从而让子进程执行不一样的代码。

2.原理:替换进程的数据段和代码段,更新堆栈。

3.exec函数簇

3.1 execl函数

int execl(const char* path,const char* argv, ...);

参数:

path:带路径的可执行程序。

arg:传递给可执行程序的命令行参数,(...表示可变参数列表),第一个参数是可执行程序本身,如果需要传递多个参数,则用“,”进行间隔,末尾以NULL结尾。

返回值:

函数如果调用成功,则加载新的程序从启动代码开始执行,不在返回;如果调用出错则返回-1

调用成功:

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   execl("/usr/bin/pwd","pwd",NULL);
   printf("if run here,the execl failed\n");
   return 0;
}

?调用失败:

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   execl("pwd","pwd",NULL);
   printf("if run here,the execl failed\n");
   return 0;
}

3.2 execlp函数

int exedlp(const char * file ,const char * arg,...);

参数:

file:可执行程序,可以不用带有路径,也可以带有路径。

arg:传递给可执行的程序的命令行参数,第一个参数,需要可执行程序本身,如果需要传递多个参数,则用“,”进行间隔,末尾以NULL结尾。

返回值:函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1。

>1file参数不带路径

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   execl("pwd","pwd",NULL);
   printf("if run here,the execl failed\n");
   return 0;
}

>2 file参数带路径

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   execl("/usr/bin/pwd","pwd",NULL);
   printf("if run here,the execl failed\n");
   return 0;
}

为什么execlp,第一个参数不用带有路径呢?

?原因就是:execlp这个函数会去搜索PATH这个环境变量,看看要替换的可执行程序是否在PATH环境变量对应的路径下能不能找到。能找到:正常替换,执行替换的程序。没找到:报错返回,替换失败了。

环境变量PATH里有/usr/bin这个路径

可执行程序不存在:

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   int ret=execlp("abcde","pwd",NULL);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

总结:

函数名当中带有"?l?”︰传递给可执行程序的参数是以可变参数列表的方式进行传递。第一个参数,需要可执行程序本身,如果需要传递多个参数,则用“,”进行间隔,末尾以NULL结尾。

函数名当中带有“?p?”:可以使用环境变量PATH,无需写全路径。换句话说,函数会搜索环境变量PATH,找到可执行程序,所以不用写路径。

3.3 execle

int execle(const char *path, const char *arg,.. .,char *const envp[ ]);

参数:

path:带路径的可执行程序(需要路径)

arg:传递给可执行的程序的命令行参数,第一个参数需要可执行程序本身,如果需要传递多个参数,则用“,”进行间隔,末尾以NULL结尾。

envp :程序员传递环境变量,换句话说,程序员调用该函数的时候,需要自己组织环境变量传递给函数。

返回值:

函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1。

总结:

函数名当中带有“e”:程序员传递环境变量,换句话说,程序员调用该函数的时候,需要自己组织环境变量传递给函数。

#include <stdio.h>
#include <stdlib.h>

int main(){
    printf("%s:%d\n",__FILE__,__LINE__);
    printf("%s\n",getenv("PATH"));
    return 0;
}
#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   extern char** environ;
   int ret=execle("/home/sy/work/usually/test","test",NULL,environ);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

?参数environ没有被设置

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   extern char** environ;
   int ret=execle("/home/sy/work/usually/test","test",NULL,NULL);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

3.4 execv函数

int execv(const char *path,char *onst argv[ ]);

参数:

path:带路径的可执行程序(需要路径)

argv :传递给可执行的程序能命令行参数,以指针数组的方式进行传递。第一个参数,需要可执行程序本身,多个参数就都放到数组当中!末尾以NULL结尾。

返回值:

函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1。

总结:

函数名字当中带有“v”:说明命令行参数是以字符指针数组的方式进行传递的,字符指针数组需要程序员自己进行定义。

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   char* argv[10]={NULL};
   argv[0]="ls";
   argv[0]="-a";
   argv[0]="-l";
   argv[1]=NULL;
   int ret=execv("/usr/bin/ls",argv);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

3.5 execvp函数

int execvp(const char* file,char *const argv[ ]);

参数:

file:可执行程序,可以不用带有路径,也可以带有路径。

argv :传递给可执行的程序的命令行参数,以指针数组的方式进行传递。第一个参数,需要可执行程序本身,多个参数就都放到数组当中末尾以NULL结尾。

返回值:

函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1。

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   char* argv[10]={NULL};
   argv[0]="ls";
   argv[0]="-a";
   argv[0]="-l";
   argv[1]=NULL;
   int ret=execvp("ls",argv);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

?3.6 execve函数

int execve(const char *path, char *const argv[ ], char *const envp[ ]);

参数:

path:带路径的可执行程序(需要路径)。

argv :传递给可执行的程序的命令行参数,以指针数组的方式进行传递。第一个参数,需要可执行程序本身,多个参数就都放到数组当中,末尾以NULL结尾。

envp :程序员传递环境变量,换句话说,程序员调用该函数的时候,需要自己组织环境变量传递给函数。

返回值:函数如果调用成功则加载新的程序从启动代码开始执行,如果调用出错则返回-1。

#include <stdio.h>
#include <unistd.h>

int main(){
   printf("in the main,proecss begin...\n");
   char* argv[10]={NULL};
   argv[0]="ls";
   argv[0]="-a";
   argv[0]="-l";
   argv[1]=NULL;
   extern char** environ;
   int ret=execve("/usr/bin/ls",argv,environ);
   printf("if run here,the execl failed,%d\n",ret);
   return 0;
}

?3.7?这些函数原型看起来很容易混,但只要掌握了规律就很好记。

l(list) : 表示参数采用列表
v(vector) : 参数用数组
p(path) : 有p自动搜索环境变量PATH
e(env) : 表示自己维护环境变量

?

3.8进程程序替换+fork+进程等待

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
   pid_t pid=fork();
       if(pid<0){
          printf("process creat failed\n");
       }
       else if(pid == 0){
           //child
           printf("i am child,exec beginning\n");
           execl("/usr/bin/ls","ls","-a","-l",NULL);
           printf("if run here,failed\n");
       }
       else{
           //father
           printf("i am father,waiting...\n");
           wait(NULL);
           
       }
  return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:14:26  更:2022-03-12 17:15:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:49:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码