博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下使用exec族函数进行进程替换
阅读量:4971 次
发布时间:2019-06-12

本文共 1882 字,大约阅读时间需要 6 分钟。

在Linux下使用fork或者vfork函数创建的子进程是完全复制父进程的代码来执行的。虽然我们可以使用fork函数返回值的不同来使得父进程和子进程执行的代码不同。但是有时候父进程是一段c程序,子进程却是个shell。这个时候,fork就没法解决这个问题。因此exec函数是必须的。

exec函数族共包括6个函数,函数形式如下:

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 execve(const char *path, char *const argv[], char *const envp[]);

注意:只有execve函数是系统调用,其余的5个都是在execve基础上封装而来的库函数。

函数参数的意义:

path:指定要执行的程序的名称和路径

file:指定要执行的程序的名称,可以不指定路径,但是必须配置环境变量PATH。

arg...:以逐个列举的方式表示要执行的程序的格式:例如准备执行“创建子进程”这个程序,那么应该传递参数为:“./创建子程序”, NULL.

argv[]:以指针数组的形式表示要执行的程序的格式。

envp[]:环境变量参数。

当一个程序中使用exec函数来调用了另外的可执行文件后,那么该进程中所有的资源完全由新进程替换。所以使用的时候应当注意,如果还想回到原来的进程继续执行,那么需要先使用fork函数来创建一个进程,在这个进程中使用exec函数来完成进程替换。这样才能保证原进程能在exec调用后不被破坏。

exec函数调用后虽然替换了进程,但是却保留PID。来段代码跑一跑

#include
#include
#include
#include
int main(){ pid_t pid; pid = fork(); if(0 == pid) { execl("./创建子进程","创建子进程",NULL); } if(0 < pid) { sleep(2); printf("I am father!\n"); } return 0;}

运行结果如下:

代码里的创建子进程是上一篇博客提到的代码,。

使用fork,而不是vfork的原因是vfork会于原进程共享地址空间,fork则是复制原进程,从而创建一个原进程的副本。vfork则在exec函数调用之前的这段时间是和父进程共享数据的,直到遇到exec函数(或者是exit函数),才会成为一个独立进程,拥有自己的地址空间。不再和父进程共享地址空间。因此使用fork可以避免很多错误。

但是使用fork的的缺点是必须无法确定执行顺序,在这里我让父进程挂起2秒,从而使得子进程先于父进程执行。另外使用exec函数也可以完成shell命令。例如下面的代码。

#include
#include
#include
#include
int main(){ pid_t pid; pid = fork(); if(0 == pid) { execl("/bin/pwd","pwd",NULL); } if(0 < pid) { sleep(1); printf("I am father process!\n"); } return 0;}

执行结果如下:

成功执行了shell命令。

转载于:https://www.cnblogs.com/zy666/p/10504278.html

你可能感兴趣的文章
错误org/aopalliance/intercept/MethodInterceptor解决方法
查看>>
两个表格中数据不用是一一对应关系--来筛选不同数据,或者相同数据
查看>>
Strict Standards: Only variables should be passed by reference
查看>>
hiho_offer收割18_题解报告_差第四题
查看>>
AngularJs表单验证
查看>>
静态方法是否属于线程安全
查看>>
02号团队-团队任务3:每日立会(2018-12-05)
查看>>
SQLite移植手记1
查看>>
js05-DOM对象二
查看>>
mariadb BINLOG_FORMAT = STATEMENT 异常
查看>>
C3P0 WARN: Establishing SSL connection without server's identity verification is not recommended
查看>>
iPhone在日本最牛,在中国输得最慘
查看>>
动态方法决议 和 消息转发
查看>>
C#生成随机数
查看>>
Android应用程序与SurfaceFlinger服务的连接过程分析
查看>>
Java回顾之多线程
查看>>
机电行业如何进行信息化建设
查看>>
9、总线
查看>>
Git 笔记 - section 1
查看>>
2018 Multi-University Training Contest 10 - Count
查看>>