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
按回车继续!
 
转载链接:http://www.cnblogs.com/blankqdb/archive/2012/08/23/2652386.html
 

exec函数族实例解析-(转自blankqdb)的更多相关文章

  1. exec函数族实例解析

    exec函数族实例解析 fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的 ...

  2. exec函数族的使用

    作者:王姗姗,华清远见嵌入式学院讲师. exec用被执行的程序完全替换调用它的程序的影像.fork创建一个新的进程就产生了一个新的PID,exec启动一个新程序,替换原有的进程,因此这个新的被exec ...

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

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

  4. Docker网络管理机制实例解析+创建自己Docker网络

    实例解析Docker网络管理机制(bridge network,overlay network),介绍Docker默认的网络方式,并创建自己的网络桥接方式,将开发的容器添加至自己新建的网络,提高Doc ...

  5. exec函数族,守护进程,线程同步和互斥

    2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...

  6. 程序清单 8-8 exec函数实例,a.out是程序8-9产生的可执行程序

    /* ============================================================================ Name : test.c Author ...

  7. [Reprint] C++函数模板与类模板实例解析

    这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下   本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...

  8. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  9. JavaWeb实现文件上传下载功能实例解析

    转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...

随机推荐

  1. 【Prometheus学习笔记】主机监控 -node_exporter

    Exporter for machine metrics prometheus/node_exporter 安装 Prometheus sudo tar -zxvf prometheus-*.tar. ...

  2. Ubuntu16.04下安装virtualbox,配置及卸载

    我是通过添加源的方式安装 将下边的命令添加到/etc/apt/source.list中 deb https://download.virtualbox.org/virtualbox/debian xe ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪

    Dapr提供了一些开箱即用的分布式链路追踪解决方案,今天我们来讲一讲如何通过dapr的configuration来实现非侵入式链路追踪的 目录:一.通过Dapr实现一个简单的基于.net的微服务电商系 ...

  4. 案例分析——Who is the king of handwriting notes?

    案例分析--Who is the king of handwriting notes? 项目 内容 这个作业属于那个课程 2021春季学期软件工程(罗杰.任健) 这个作业的要求在哪里 案例分析 我在这 ...

  5. Python表达式进阶——列表表达式

    x = 0 y = x*2 if x >= 0 else x print(y) # [表达式for变量in列表] l1 = [] l2 = [i for i in range(100) if i ...

  6. 1144 The Missing Number

    Given N integers, you are supposed to find the smallest positive integer that is NOT in the given li ...

  7. ASP封装DLL 直接上代码

    ASP转DLL 基本引用类库 OLE Automation Com+ services Type Library Microsoft Active Server Pages Object Micros ...

  8. 5-tcp套接字服务端编程

    import socket 1.创建套接字 sockfd= socket.socket(socket_family = AF_INIT,socket_type=SOCK_STREAM,proto) 功 ...

  9. CVE-2017-11882:Microsoft office 公式编辑器 font name 字段栈溢出通杀漏洞调试分析

    \x01 漏洞简介 在 2017 年 11 月微软的例行系统补丁发布中,修复了一个 Office 远程代码执行漏洞(缓冲区溢出),编号为 CVE-2017-11882,又称为 "噩梦公式&q ...

  10. nodejs-REPL/回调函数/事件循环

    REPL 回调函数 事件循环 REPL----------------------------------------------------- Node.js REPL(Read Eval Prin ...