转载:http://www.cnblogs.com/blankqdb/archive/2012/08/23/2652386.html

fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。linux将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。),也就是这两个进程做完全相同的事。

在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事)。

fork创建一个新的进程就产生了一个新的PID,exec启动一个新程序,替换原有的进程,因此这个新的被 exec 执行的进程的PID不会改变(和调用exec的进程的PID一样)。

exec函数族:

 1 #include <unistd.h>
 2 extern char **environ;
 3 int execl(const char *path,
 4           const char *arg, ...);
 5 int execlp(const char *file,
 6            const char *arg, ...);
 7 int execle(const char *path,
 8            const char *arg,
 9            ...,
10            char * const envp[]);
11 int execv(const char *path,
12           char *const argv[]);
13 int execvp(const char *file,
14            char *const argv[]);
15 int execve(const char *file,
16             char *const argv[],
17             char *const envp[]);

exec函数族装入并运行程序path/file,并将参数arg0(arg1, arg2, argv[], envp[])传递给子程序,出错返回-1.

在exec函数族中,后缀l、v、p、e指定函数将具有某种操作能力:

后缀 操作能力
l 希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志
v 希望接收到一个以NULL结尾的字符串数组的指针
p 是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件
e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境

具体例子:

  1 #ifdef HAVE_CONFIG_H
  2 #include <config.h>
  3 #endif
  4
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <unistd.h>
  8 #include <string.h>
  9 #include <errno.h>
 10
 11 int main(int argc, char *argv[])
 12 {
 13   //以NULL结尾的字符串数组的指针,适合包含v的exec函数参数
 14   char *arg[] = {"ls", "-a", NULL};
 15
 16   /**
 17    * 创建子进程并调用函数execl
 18    * execl 中希望接收以逗号分隔的参数列表,并以NULL指针为结束标志
 19    */
 20   if( fork() == 0 )
 21   {
 22     // in clild
 23     printf( "1------------execl------------\n" );
 24     if( execl( "/bin/ls", "ls","-a", NULL ) == -1 )
 25     {
 26       perror( "execl error " );
 27       exit(1);
 28     }
 29   }
 30
 31   /**
 32    *创建子进程并调用函数execv
 33    *execv中希望接收一个以NULL结尾的字符串数组的指针
 34    */
 35   if( fork() == 0 )
 36   {
 37     // in child
 38     printf("2------------execv------------\n");
 39     if( execv( "/bin/ls",arg) < 0)
 40     {
 41       perror("execv error ");
 42       exit(1);
 43     }
 44   }
 45
 46   /**
 47    *创建子进程并调用 execlp
 48    *execlp中
 49    *l希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志
 50    *p是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件
 51    */
 52   if( fork() == 0 )
 53   {
 54     // in clhild
 55     printf("3------------execlp------------\n");
 56     if( execlp( "ls", "ls", "-a", NULL ) < 0 )
 57     {
 58       perror( "execlp error " );
 59       exit(1);
 60     }
 61   }
 62
 63   /**
 64    *创建子里程并调用execvp
 65    *v 望接收到一个以NULL结尾的字符串数组的指针
 66    *p 是一个以NULL结尾的字符串数组指针,函数可以DOS的PATH变量查找子程序文件
 67    */
 68   if( fork() == 0 )
 69   {
 70     printf("4------------execvp------------\n");
 71     if( execvp( "ls", arg ) < 0 )
 72     {
 73       perror( "execvp error " );
 74       exit( 1 );
 75     }
 76   }
 77
 78   /**
 79    *创建子进程并调用execle
 80    *l 希望接收以逗号分隔的参数列表,列表以NULL指针作为结束标志
 81    *e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境
 82    */
 83   if( fork() == 0 )
 84   {
 85     printf("5------------execle------------\n");
 86     if( execle("/bin/ls", "ls", "-a", NULL, NULL) == -1 )
 87     {
 88       perror("execle error ");
 89       exit(1);
 90     }
 91   }
 92
 93   /**
 94    *创建子进程并调用execve
 95    * v 希望接收到一个以NULL结尾的字符串数组的指针
 96    * e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境
 97    */
 98   if( fork() == 0 )
 99   {
100     printf("6------------execve-----------\n");
101     if( execve( "/bin/ls", arg, NULL ) == 0)
102     {
103       perror("execve error ");
104       exit(1);
105     }
106   }
107   return EXIT_SUCCESS;
108 }

运行结果(linux):

1------------execl------------
.  ..  .deps  exec  exec.o  .libs  Makefile
2------------execv------------
.  ..  .deps  exec  exec.o  .libs  Makefile
3------------execlp------------
.  ..  .deps  exec  exec.o  .libs  Makefile
4------------execvp------------
.  ..  .deps  exec  exec.o  .libs  Makefile
5------------execle------------
.  ..  .deps  .libs  Makefile  exec  exec.o
6------------execve-----------
.  ..  .deps  .libs  Makefile  exec  exec.o
按回车继续!

exec函数族实例解析相关推荐

  1. php正则表达式实例详解,正则表达式实例解析

    正则表达式实例解析 类别: 技术 时间:2016-06-02 10:14:14 字数:6253 版权所有,未经允许,请勿转载,谢谢合作~ ### 前言 正则表达式(regular expression ...

  2. UNIX再学习 -- exec 函数族

    我们在讲,文件I/O的时候,简单提到过 exec 函数,讲到 vfork 的时候,也有用到.下面我们来详细介绍下它. 参看:UNIX再学习 -- 文件I/O  参看:UNIX再学习 -- 函数 for ...

  3. Qt文档阅读笔记-Multiple Inheritance Example 实例解析及Automatic Connections解析

    目录 Multiple Inheritance Example 实例解析 Automatic Connections解析 Multiple Inheritance Example 实例解析 这个实例很 ...

  4. Qt文档阅读笔记-QIODevice解析及Audio Example实例解析

    目录 QIODevice官方解释及个人分析 Audio Example官方实例解析 QIODevice官方解释及个人分析 QIODevice类是Qt中I/O设备的接口. 提供了读和写的接口,QIODe ...

  5. exec函数族的作用与讲解

    apue看到第八章,对exec函数族的理解一直都很混乱,总觉得不对劲儿,其实不能理解的先暂时跳过,看到后面,再结合实例也就慢慢的理解了. 以下内容转自:http://www.cppblog.com/p ...

  6. 小何讲进程:Linux中的exec函数族讲解

    1.  exec函数族-exec()函数族说明 使用exec函数族主要有两种情况 当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用exec函数族中的任意一个函数让自己重生: 如果一个进程想执 ...

  7. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析

    Java Collections.swap()方法解析 jdk源码: public static void swap(List<?> list, int i, int j) {// ins ...

  8. python argparse模块_Python argparse模块应用实例解析

    这篇文章主要介绍了Python argparse模块应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 简介 argparse是python ...

  9. exec函数族的使用

    调用shell脚本命令:execlp("sh","sh","filename",(char*)0); exec用被执行的程序完全替换调用它的 ...

最新文章

  1. 我摊牌了,大厂面试Linux就这5个问题
  2. C语言open和creat函数
  3. c语言水印添加,[求助]C语言 bmp文件加上水印
  4. 儿童吹泡泡水简单配方_儿童吹泡泡水简单配方[组图]
  5. Linux网络编程——黑马程序员笔记
  6. Windows 2008 R2阿里云安全基线检查
  7. oracle中exp/imp讲解
  8. C#内存流示例-----gt;用内存流来读取图片
  9. SQL SERVER 2005 数据挖掘与商业智能完全解决方案---学习笔记(一)
  10. 程序functionLua基础 小结(两个Lua程序示例)
  11. [搬运] 写给 C# 开发人员的函数式编程
  12. CAN:CANape使用Function处理数据
  13. 咸阳机场地下停车场如何收费,咸阳机场停车收费价格
  14. 用金山打字通练习打字
  15. 新版TCGA的突变SNP数据添加临床信息
  16. Nginx解决无法代理域名问题
  17. HTML和CSS中的图像与背景图像
  18. 常见SOC启动流程分析
  19. 微信关注事件bug记录
  20. 数据库系统概念 实验1~实验9

热门文章

  1. spring boot高性能实现二维码扫码登录(上)——单服务器版
  2. numpy 辨异(三)—— hstack/column_stack,linalg.eig/linalg.eigh
  3. android 处理鼠标滚轮事件 【转】
  4. 在一个字符串中找到第一个只出现一次的字符
  5. 上周热点回顾(7.8-7.14)
  6. Gridview应用技巧——如何为行添加事件
  7. 扩大swap分区--Ubuntu手记之系统配置
  8. 是否会成为问题——Linq to Sql的执行可能无法复用查询计划
  9. ruby sinatra mysql_一分钟开始持续集成之旅系列之:Ruby + Sinatra 应用
  10. python构建矩阵 x y_生成Python函数一半没问题,当前最正统的代码生成是什么样的?...