博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
执行新程序以及环境变量
阅读量:5108 次
发布时间:2019-06-13

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

关键字:子进程,exec,环境变量

使用fork或vfork创建子进程后,子进程通常会调用exec函数来执行另外一个程序。系统调用exec用于执行一个可执行程序以

替代当前进程的执行映像。

注意:exec调用并没有创建新的进程。一个进程一旦调用exec函数,它本身就“死亡”了,系统把代码段替换成新的程序的代码,

废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一保留的就是进程ID。也就是说,对系统而言,还是

同一个进程,不过执行的已经是另外一个程序了。

exec函数:

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[]);

--------------------------------------------------------------------------------

环境变量:用户的主目录,终端类型,当前目录等,它们定义了用户的工作环境,所以称为环境变量。

可以使用指令env查看系统环境变量。

用户也可以修改这个变量的值,以制定自己的工作环境。

代码中通过系统预定义的全局变量environ显示各个环境变量的值。

事实上main函数的完整形式应该是:

int main(int argc, char* argv[], char** envp);

参数envp就是系统环境变量。

测试代码:

#include 
#include
extern char** environ;int main(int argc, char** argv, char** envp){ char** p = environ; char** q = envp; while(*p != NULL) { printf("%s\n", *p++); printf("%s\n", *q++); printf("----------\n"); } return 0;}

 

 

-----------------------------------------------------------------------------------------------

exec函数与环境变量的关系:

无论是哪个exec函数,都是可以将可执行程序的路径、命令行参数和环境变量3个参数传递给可执行程序的main函数。

程序一:p.c

#include 
#include
#include
int main(int argc, char* argv[], char **envp){ int i = 0; printf("after execve, my pid is:%d\n", getpid()); for(i=0;i

  

 

程序二:ex.c

#include 
#include
#include
#include
int main(int argc, char* argv[], char* envp[]){ pid_t pid = 0; int stat; printf("test execve\n"); pid = fork(); if (pid < 0) { exit(0); } else if (pid == 0) { printf("the child's pid is:%d\n", getpid()); execve("p", argv, envp); printf("go on run\n"); } printf("parent is running\n"); wait(&stat); printf("quit\n"); return 0;}

 

 

将第一个程序编译:

gcc -o p p.c

编译第二个程序:

gcc -o ex ex.c 

执行ex程序:

 

test execve

parent is running
the child's pid is:26152
after execve, my pid is:26152
argv[0]=./ex
argv[1]=ll
quit

 

从执行结果来看,execve调用的程序,保持了原来的进程ID,父进程ID。

同时,我们还可以看到当调用新的可执行程序后,原有的子进程的映像被替代,不在被执行。

子进程不会去执行printf("go on run\n");因为子进程已经被新的执行映像替代。

 

执行新程序后的进程保持了原来进程的许多特征,如:

1、文件锁

2、控制终端

3、当前工作目录

4、根目录

5、创建文件时使用的屏蔽字

6、进程信号屏蔽字

7、未决警告

8、和进程相关的使用处理器的时间

9、实际用户ID

10、实际组ID

转载于:https://www.cnblogs.com/zhangxuan/p/6420524.html

你可能感兴趣的文章
oracle 几个时间函数探究
查看>>
第一个Java Web程序
查看>>
Atomic
查看>>
div 显示滚动条与div显示隐藏的CSS代码
查看>>
Redis-1-安装
查看>>
Access denied for user ''@'localhost' to database 'mysql'
查看>>
部署支持 https 的 Nginx 服务
查看>>
WebAssembly是什么?
查看>>
树状数组_一维
查看>>
如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:
查看>>
linux install ftp server
查看>>
嵌入式软件设计第8次实验报告
查看>>
算法和数据结构(三)
查看>>
在iOS 8中使用UIAlertController
查看>>
Ubuntu下的eclipse安装subclipse遇到没有javahl的问题...(2天解决了)
查看>>
Atcoder Grand Contest 004 题解
查看>>
alter database databasename set single_user with rollback IMMEDIATE 不成功问题
查看>>
idea 系列破解
查看>>
Repeater + Resources 列表 [原创][分享]
查看>>
c# Resolve SQlite Concurrency Exception Problem (Using Read-Write Lock)
查看>>