fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程不共享这些存储空间。linux将复制父进程的地址空间内容给子进程,因此,子进程由了独立的地址空间。),也就是这两个进程做完全相同的事。
在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事
exec函数族可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段。在执行完后,原调用进程的内容除了进程号外,其它全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。
在Linux中使用exec函数族主要有一下两种情况
当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec函数族让自己重生;
如果一个进程想执行另外一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生
实际上linux并没有exec函数,而是有6个exec开头的函数。函数用法如下:

这6个函数的区别如下:

  • 查找方式:上表中前4个函数的查找方式都是完整的文件目录路径(即绝对路径),而最后两个函数(也就是以p结尾的两个函数)可以只给出文件名,系统就会自动从环境变量“$PATH”所指出的路径中进行查找。
  • 参数传递方式:有两种方式,一种是逐个列举的方式,另一种是将所有参数整体构造成一个指针数组进行传递。(在这里,字母“l”表示逐个列举的方式,字母“v”表示将所有参数整体构造成指针数组进行传递,然后将该数组的首地址当做参数传递给它,数组中的最后一个指针要求时NULL)
  • 环境变量:exec函数族使用了系统默认的环境变量,也可以传入指定的环境变量。这里以“e”结尾的两个函数就可以在envp[]中指定当前进程所使用的环境变量替换掉该进程继承的所有环境变量

exec后新进程保持原进程以下特征

环境变量(使用了execle、execve函数则不继承环境变量);

进程ID和父进程ID;

实际用户ID和实际组ID;

附加组ID;

进程组ID;

会话ID;

控制终端;

当前工作目录;

根目录;

文件权限屏蔽字;

文件锁;

进程信号屏蔽;

未决信号;

资源限制;

tms_utime、tms_stime、tms_cutime以及tms_ustime值。

下面来看下实际的函数用法:

下面的这个函数是执行shell的ls命令。由于使用execle因此指定了ls命令的路径/bin/ls。

void exec_function_try(){

pid_t pid;

if ((pid = fork()) < 0){

printf("error");

}

else if (pid == 0){

if(execle("/bin/ls","-al",(char *)0,env_init) < 0)

printf("error for execle");

}

}

运行结果。列出了当前工程目录下的所有文件

上面的这个函数是执行shell命令。下面的这个函数执行的是另外一个c文件

void exec_function(){

pid_t pid;

if ((pid = fork()) < 0){

printf("error");

}

else if (pid == 0){

if(execle("/home/zhf/c_prj/test","echoall","myarg1","MY ARG2",(char *)0,env_init) < 0)

printf("error for execle");

}

if ((pid == fork()) < 0){

printf("error");

}

else if (pid == 0){

if(execlp("test","echoall","only 1 arg","MY ARG2",(char *)0) < 0)

printf("error for execlp");

}

}

test.c的代码如下:

#include<stdlib.h>

#include<stdio.h>

int main(int argc,char *argv[]){

int i;

char **ptr;

extern char **environ;

for(int i=0;i<argc;i++)

printf("argv[%d]:%s\n",i,argv[i]);

for(ptr=environ;*ptr!=0;ptr++)

printf("%s\n",*ptr);

exit(0);

}

首先执行gcc -g -o test test.c生成可执行的test文件,然后在exec_function中就可以被引用。

执行结果如下

linux c编程:进程控制(三)_exec函数的更多相关文章

  1. Unix环境高级编程—进程控制(三)

    一.解释器文件 解释器文件属于文本文件,起始行形式为: #! pathname[optional-argument] 我们创建一个只有一行的文件如下: #!/home/webber/test/echo ...

  2. Linux系统编程@进程通信(一)

    进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...

  3. Linux系统编程@进程管理(一)

    课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...

  4. Linux系统编程_8_进程控制之fork_wait_waitpid函数

    fork函数: #include <unistd.h>        pid_t fork(void); fork用来创建一个子进程: 特点: fork调用后会返回两次,子进程返回0,父进 ...

  5. 进程控制之fork函数

    一个现有进程可以调用fork函数创建一个新进程. #include <unistd.h> pid_t fork( void ); 返回值:子进程中返回0,父进程中返回子进程ID,出错返回- ...

  6. Linux多任务编程——进程

    进程编程常用函数 1--- fork pitd_t fork(void); 创建一个新的子进程,其父进程为调用 fork() 函数的进程: 返回值:成功:子进程返回 0,父进程返回 子进程 PID:失 ...

  7. 进程控制之exec函数

    用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序.当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行.因为调用exec并不创 ...

  8. Linux C 程序 进程控制(17)

    进程控制 1.进程概述现代操作系统的特点在于程序的并行执行.Linux是一个多用户多任务的操作系统.ps .pstree 查看进程进程除了进程id外还有一些其他标识信息,可以通过相应的函数获得.// ...

  9. 进程控制之system函数

    ISO C定义了system函数,但是其操作对系统的依赖性很强.POSIX.1包括了system接口,它扩展了ISO C定义,以描述system在POSIX.1环境中的运行行为. #include & ...

随机推荐

  1. xtrabackup详解

    xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具,具有开源,免费,支持在线热备,备份恢复速度快,占用磁盘空间小等特点,并且支持不同情况下的多种备份 ...

  2. UVA10312- Expression Bracketing(Catalan + 递推)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=1253">题目链接 题意:给出一个序列,长 ...

  3. ubuntu+tomcat,多环境、自动化部署脚本,git+maven+tomcat+ubuntu

     1.切换到/opt/code目录,没有利用mkdir code创建code目录,新建deploy.sh 脚本文件,内容如下 projectName=""; #默认tomcat目录 ...

  4. 升级滑动销毁activity,随着手势的滑动而滑动的效果

    文章开头先注明本滑动销毁是对 http://blog.csdn.net/xiaanming/article/details/20934541 这篇博客的内容进行一个小小的改动 添加向左滑动打开另外一个 ...

  5. [DevExpress]TreeListLookUpEdit带checkbox之经典运用

    上代码: public partial class TreeListLookUpEdit : DevExpress.XtraEditors.XtraForm { private string _Key ...

  6. xgboost 特征选择,筛选特征的正要性

    import pandas as pd import xgboost as xgb import operator from matplotlib import pylab as plt def ce ...

  7. Linux 下安装PHPunit

    PHP 档案包 (PHAR)  要获取 PHPUnit,最简单的方法是下载 PHPUnit 的 PHP 档案包 (PHAR),它将 PHPUnit 所需要的所有必要组件(以及某些可选组件)捆绑在单个文 ...

  8. 《大话操作系统——做坚实的project实践派》(4)

     操作系统内核必需要关注一个详细硬件平台的设备 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG1ub3M=/font/5a6L5L2T/fontsi ...

  9. How to Use HTML5 FUll Screen API(怎样使用HTML5全屏接口)

    原文链接:http://www.sitepoint.com/use-html5-full-screen-api/ 假设你不太喜欢变化太快的东西,那么web开发可能不适合你. 我曾在2012年末有写过F ...

  10. MySQL:习题(单表多条件查询二)

    Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...