Linux 进程创建二(execve和wait)

摘要:
通常设置为NULL//execve函数定义#include<NULL};NULL);}wait和waitpid函数可以收集子进程的退出状态pid(int*status);他可以接受以下四个值:“<0”。等待PID等于PID的子进程//等待函数#include<未发布h>intstatus=0;child=fork();睡眠(3);
三:execve系统调用
int execve(const char *filename, char *const argv[],char *const envp[]);
fork创建了一个新的进程,产生一个新的PID
execve用被执行的程序完全替换了调用进程的映像。
execve启动一个新程序,替换原有进程,所以被执行进程的PID不会改变。
execve函数接受三个参数
--path    要执行的文件完整路径
--argv    传递给程序完成参数列表,包括argv[0],它一般是执行程序的名字,最后一个参数一般是NULL
--envp    是指向执行execed程序的环境指针,一般设为NULL
//execve函数的定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int main(int arg, char * args[])
{
    /*
      第一个参数是程序的名字,第二个参数是被调用程序的参数,最后一个参数必须是NULL
      这个跟main函数的参数args数组很相似
     */
    char * argv[]={"/bin/ls","-l",NULL};
    execve("/bin/ls",argv,NULL);
    /*
     execve函数是替换原来的程序代码,但是进程PID不会变,文件描述符不会变,只是程序代码被替换了
     所以execve函数后面的语句都不会被执行
     */
    printf("program is end!
");
    return 0;
}
wait和waitpid函数可以收集子进程的退出状态
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
stauts保存子进程的退出状态(本质上就是子进程的返回值,但是我们不能直接查看这个返回值,必须用宏定义转化一下)
在waitpid函数中,参数pid是等待进程的PID,他能够接受一下四种值
    "<-1"    等待任何PGID等于PID的绝对值子进程
    "-1"    等待任何子进程(这个进程创建的子进程)
    "0"    等待任何PGID等于调用进程的子进程
    ">0"    等待PID等于pid的子进程    
//wait函数的定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int arg, char * args[])
{
    pid_t child=0;
    int status=0;
    child=fork();
    if(child==-1)
    {
        printf("system is game over!
");
        return -1;
    }
    if(child==0)
    {
        //in child process
        printf("child is begining!
");
        sleep(3);
        printf("child is end , now is your turn!
");
    }else{
        //in parent process
        printf("parent is begining , i am wait my son!
");
        wait(&status);
        printf("child status=%d
",WEXITSTATUS(status));
        printf("my son is end , now i am go !
");
    }
    printf("all is end!
");
    return 10;
}

Linux 进程创建二(execve和wait)第1张 

用fork或者execve函数创建一个新进程,为了收集新进程的退出状态并且防止出现僵死进程(zombie process),父进程应该调用wait或者waitpid函数等待进程终止。
僵死进程
一个僵死进程是在父进程退出之前就终止的子进程(子进程在父进程之前终止,此时因为父进程还没有退出,所以系统会保留子进程的pid,退出
状态,返回给父进程有wait函数,如果父进程没有wait函数,系统就会一直保持子进程的PID等信息,直到父进程退出)
之所以被称为僵死进程是因为他虽然死掉了,但依然在进程表中存在。
子进程退出后分配给他的内存和其他资源都被释放,但是子进程还在内核进程表保留一条,内核在父进程回收子进程的退出状态前一直保留它。
有一个两个僵死进程不算什么问题,但一旦一个程序频繁执行fork或者execv却又不能手机退出状态,那么最终将会填满进程表(内核进程表是有上限的),这会影响性能,可能导致系统重启

Linux 进程创建二(execve和wait)第2张

孤儿进程
孤儿进程是一个父进程在调用wait或者waitpid之前就已经退出了(即父进程在子进程之前退出)。此时init进程成为子进程的父进程。
init进程成为子进程的父进程,收集子进程的退出状态,从而避免出现僵死进程。
注意:任何一个进程都必须有父进程,init的父进程是0号进程,父进程与子进程是相对独立的(子进程会拷贝进程控制器和代码区,写时拷贝数据区),父进程退出,子进程不一定会退出

免责声明:文章转载自《Linux 进程创建二(execve和wait)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇训练集,验证集,测试集(以及为什么要使用验证集?)(Training Set, Validation Set, Test Set)使用作业定时压缩数据库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于项目架构的一些浅谈

         最近,一直在学习和摸索关于项目架构的东东。或许说架构说得有点太大。但是还是暂且用着吧。 也看看过几个高手关于三层架构和MVC模型的文章,觉得很多东西的理解和自己的不是很一样。但是自己确实没有他们研究的深入,所以也不妄加评论。         在这里想说的是,自己幼稚的观点欢迎各位砸砖;自己绝对的言语只是针对自己的想法。         我...

操作系统/应用程序、操作中的“并发”、线程和进程,python中线程和进程(GIL锁),python线程编写+锁

并发编程前言:       1、网络应用            1)爬虫 直接应用并发编程;            2)网络框架 django flask tornado 源码-并发编程            3)socketserver 源码-并发编程       2、运维领域            1)自动化开发-运维开发(机器的批量管理,任务的批量执...

Qt 自定义事件

Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展。在 Qt 中,你需要继承的类是 QEvent。 继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定义事件的类型值。这里的QEvent::Type类型是QEvent里面定义的一个enum,因此,你是可以传递一个int的。重要的是,你的事件类型不能和已经存在的...

(转)Android Studio 增加函数注释模板

此篇文章主要介绍如何在Android Studio中函数如何添加注释,使其和eclipse一样方便的添加注释 Android Studio默认函数注释为 /** * */ 下面方法将要改为如下格式 1 2 3 4 5 /**  *  * @author zony  * @time 15-11-25 下午2:41  */...

TS Eslint规则说明

"no-alert": 0,//禁止使用alert confirm prompt "no-array-constructor": 2,//禁止使用数组构造器 "no-bitwise": 0,//禁止使用按位运算符 "no-caller": 1,//禁止使用arguments.caller或arguments.callee "no-catch-sha...

LINUX内核分析第四周——扒开系统调用的三层皮

LINUX内核分析第四周——扒开系统调用的三层皮 李雪琦 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一、用户态、内核态和中断处理过程 1. 用户态和内核态 CPU指令执行级别: 执行特权指令,访问任意的物理地址——内核态。 低级别:代...