Linux进程fork,exec,vfork详解

在Unix/Linux系统下进程创建时需要进行如下系统调用:fork/exec

fork()把一个进程复制成二个进程:parent (old PID), child (new PID)

exec()用新程序来重写当前进程:PID没有改变

接下来就重点学习这两个系统调用:

当我们fork() 创建一个继承的子进程将会发生如下事情:复制父进程的所有变量和内存,复制父进程的所有CPU寄存器(有一个寄存器例外)(这个寄存器是用来区分父进程和子进程的PID)

fork()的返回值:调用fork()函数成功时,将会有两个返回值。子进程的fork()返回0,父进程的fork()返回子进程标识符。fork() 返回值可方便后续使用,子进程可使用getpid()获取PID。

fork()执行过程对于子进程而言,是对父进程地址空间的一次复制。下面我们通过图示来看一下这个复制过程:

注意了,图示中的两个childPID的值是不同的,对于父进程中的childPID当然是子进程的PID,而子进程中的childPID的值为0。

fork()使用示例:

int  main()
{
	pid_t  pid;
	int  i;

	for(i=0;  i<LOOP;  i++)
    {
           /* 创建新进程*/
    	pid = fork();
        if  (pid < 0) { /*创建失败  */
        fprintf(stderr, “Fork Failed”);
            exit(-1);
        }
        else if (pid == 0) { /* 子进程 */
            fprintf(stdout,  “i=%d,  pid=%d,  parent  pid=%d\n”,I,
                    getpid() ,getppid());
        }
      }
    wait(NULL);
    exit(0);
} 

了解了fork()之后我们再来看看exec()系统调用:系统调用exec( )加载新程序取代当前运行进程,也就是说exec调用成功时,它是相同的进程,但是运行了不同的程序,代码段、堆栈和堆(heap)等也都完全重写了。它允许进程“加载”一个完全不同的程序,并从main开始执行,而我们的fork()创建出来的子进程是从fork()之后的代码段处开始执行的。

我们接下来讨论一下fork()的实现开销:当我们使用fork()系统调用时,首先要对子进程分配内存,然后复制父进程的内存和CPU寄存器到子进程里。开销昂贵!!

然而在99%的情况里,我们在调用fork()之后调用exec(),因为在大多数情况下我们都是不希望和父进程执行同样的代码,不然的话我们创建一个新的进程也就没有多大的意义了。这时候我们就该考虑一下这个问题了:既然不想使用父进程中的代码,在fork()操作中内存复制就是没有作用的。那么为什么不能结合它们在一个调用中?

此后,就产生了vfork():创建进程时,不再创建一个同样的内存映像。一些时候称之为轻量级fork(),子进程几乎立即调用exec()。而在子进程调用exec()之前,暂时与父进程共享地址空间。

我们注意到了,前面fork()的示例代码中使用了wait()函数,那么这个函数是干什么用的呢?这就要引出一个新的概念了:父进程等待子进程

wait()系统调用用于父进程等待子进程的结束:子进程结束时通过exit()向父进程返回一个值,父进程通过wait()接受并处理返回值

wait()系统调用的功能:有子进程存活时,父进程进入等待状态,等待子进程的返回结果。当某子进程调用exit()时,唤醒父进程,将exit()返回值作为父进程中wait的返回值

既然子进程结束时是通过exit()向父进程返回一个值,那么我们又要学习一下exit()系统调用了:

进程结束执行时调用exit(),完成进程资源回收

exit()系统调用的功能:

  • 将调用参数作为进程的“结果”
  • 关闭所有打开的文件等占用资源
  • 释放内存
  • 释放大部分进程相关的内核数据结构
  • 检查是否父进程是存活着的,如存活,保留结果的值直到父进程需要它,进入僵尸(zombie/defunct)状态。如果没有,它释放所有的数据结构,进程结果
  • 清理所有等待的僵尸进程

说到这里,大家可能对僵尸进程有点疑惑:所谓的僵尸进程,就是父进程没有调用wait收集子进程的退出状态,子进程就已经退出了,此时这个退出的子进程就成为了僵尸进程,它的很多进程资源都还没有释放(例如PID在进程表中仍然存在)。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-26 10:55:01

Linux进程fork,exec,vfork详解的相关文章

Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)【转】

转自:http://blog.csdn.net/gatieme/article/details/51872659 版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatieme 目录(?)[-] 前景回顾 1 Linux的调度器组成 2 调度工作 进程上下文 1 进程上下文的概念 2 上下文切换 context_switch进程上下文切换 1 context_switch完全注释 2 prepare_arch_switch切换前的准备工作

Linux进程管理相关命令详解

一.top top命令用于显示系统当前的进程和其他状况:top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果再前台执行该命令,它将独占前台,直到用户终止该程序为止. 其中1-5行为统计信息区,剩余行为进程信息区:1.统计信息区1)第1行为任务队列信息(与uptime命令运行结果相同)字段含义:当前时间     系统启动持续时间   当前登陆用户数    系统负载,即任务队列的平均长度备注:格式为"日期,时:分"  三个数值分别为1,5和15分钟前到现在的均值2)第2行为

Linux守护进程简介和实例详解

简介 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进程.Linux的大多数服务器就是用守护进程实现的.比如,Internet服务器inetd,Web服务器httpd等.同时,守护进程完成许多系统任务.比如,作业规划进程crond,打印进程lpd等. 下面是linux系统中常见的一些守护进程. amd:自动安装NFS(网络文件系统)守侯进程apmd:高级电源管理 Arpwatch:记录日志并构建一个在L

Linux网络编程——进程池实现过程详解(1)

目录 进程池 父进程的实现流程 子进程的实现流程 进程池 父进程的实现流程 1.定义数据结构pChild,申请子进程数目的结构体空间 2.通过循环,socketpair创建全双工管道,创建子进程,将子进程pid,管道对端,是否忙碌等信息存储 3.socket,bind,listen,对应的端口处于监听状态 netstat 4.epoll_create创建epfd,监控socketFd和所有子进程的管道对端 5.while(1)循环 epoll_wait等待客户端的请求及子进程是否有通知 如果so

Linux进程控制——exec函数族

原文:http://www.cnblogs.com/hnrainll/archive/2011/07/23/2114854.html 1.简介 在Linux中,并不存在exec()函数,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char

Linux基础知识之挂载详解(mount,umount及开机自动挂载)

Linux基础知识之挂载详解(mount,umount及开机自动挂载) 转载自:http://www.linuxidc.com/Linux/2016-08/134666.htm 挂载概念简述: 根文件系统之外的其他文件要想能够被访问,都必须通过"关联"至根文件系统上的某个目录来实现,此关联操作即为"挂载",此目录即为"挂载点",解除此关联关系的过程称之为"卸载" 1.挂载:根文件系统外通过关联至根文件系统上的某个目录来实现访问

exec命令详解

exec: 在bash下输入man exec,找到exec命令解释处,可以看到有"No new process is created."这样的解释,这就是说exec命令不产生新的子进程.那么exec与source的区别是什么呢? exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行. 1. 系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变.因此,可以这样认为,exec系统调用并没有创建新的进程,只是替换了原来进程上下文的内容.原进

Linux上的free命令详解

Linux上的free命令详解 转自: http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html 解释一下Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO(Free Output).例如: FO[2][1] = 24677460 FO[3][2] = 10321516 1          2          3    

linux TOP命令各参数详解【转载】

实时监控或查看系统资源使用情况的工具——TOP top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. 下面详细介绍它的使用方法: (实时监控系统资源使用情况图) 统计信息区前五行是系统整体的统计信息: 第一行是任务队列信息,同 uptime  命令的执行结果.其内容如下: 01:06:48 当前时间 up 1:22 系统运行时间,格式为时:分 1 user 当前登录用户数 load average: 0.06, 0.60, 0.