三:execve系统调用
int execve(const char *filename, char *const argv[],char *const envp[]);
fork创建了一个新的进程,产生一个新的PID
execve用被执行的程序完全替换了调用进程的映像。
execve启动一个新程序,替换原有进程,所以被执行进程的PID不会改变。
execve函数接受三个参数
--path 要执行的文件完整路径
--argv 传递给程序完成参数列表,包括argv[],它一般是执行程序的名字,最后一个参数一般是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!\n");
return ;
}
wait和waitpid函数可以收集子进程的退出状态
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
stauts保存子进程的退出状态(本质上就是子进程的返回值,但是我们不能直接查看这个返回值,必须用宏定义转化一下)
在waitpid函数中,参数pid是等待进程的PID,他能够接受一下四种值
"<-1" 等待任何PGID等于PID的绝对值子进程
"-" 等待任何子进程(这个进程创建的子进程)
"" 等待任何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=;
int status=;
child=fork();
if(child==-)
{
printf("system is game over!\n");
return -;
}
if(child==)
{
//in child process
printf("child is begining!\n");
sleep();
printf("child is end , now is your turn!\n");
}else{
//in parent process
printf("parent is begining , i am wait my son!\n");
wait(&status);
printf("child status=%d\n",WEXITSTATUS(status));
printf("my son is end , now i am go !\n");
}
printf("all is end!\n");
return ;
}

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

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

Linux 进程创建二(execve和wait)的更多相关文章

  1. Linux进程管理(二)

    目录 Linux进程管理(二) 参考 vmstat命令 top命令 Linux进程管理(二)

  2. Linux 进程创建一(system和fork)

    一:system系统调用 #include <stdlib.h> int system(const char *string); system函数传递给/bin/sh -c 来执行stri ...

  3. Linux进程创建和结束

    在Linux中,进程的创建由系统调用fork和vfork完成.它们生成一个子进程并且子进程是父进程的一个复制品. Fork系统调用对应的kernel函数是sys_fork,此函数简单的调用kernel ...

  4. linux进程创建

    1.  进程是程序的执行,会被加载到内存中,每个进程包括程序的代码和数据,其中数据包括程序的变量的数据,外部数据,程序堆栈. 2. Linux中,输入命令,如vi main.c 通过shell来执行, ...

  5. linux 进程创建clone、fork与vfork

    目录: 1.clone.fork与vfork介绍 2.fork说明 3.vfork说明 4.clone说明5.fork,vfork,clone的区别 内容: 1.clone.fork与vfork介绍 ...

  6. linux进程篇 (二) 进程的基本控制

    2. 进程的基本操作 接口函数 #include <unistd.h> //创建子进程 pid_t fork(void); //结束子进程 void exit(int status); / ...

  7. Linux 进程(二):进程关系及其守护进程

    进程关系 进程组 进程组是一个或多个进程的集合.通常,它们是在同一作业中结合起来的,同一进程组中的各进程接收来自同一终端的各种信号,每个进程组有一个唯一的进程组ID.每个进程组有一个组长进程,该组长进 ...

  8. linux进程(二)

    信号管理进程使用kill命令发送信号与进程通信定义守护进程的角色结束用户会话的进程 kill,killall,pgrep,pkill 对于进程的正常关闭的理解正常关闭程序的方法systemctl st ...

  9. 二十二、Linux 进程与信号---进程创建

    22.1 fork 和 vfork 函数 22.1.1 函数说明 #include <unistd.h> #include <sys/types.h> pid_t fork( ...

随机推荐

  1. ethtool 命令输出的注意点--网卡参数

    http://blog.csdn.net/msdnchina/article/details/70339689

  2. Step by Step 使用HTML5开发一个星际大战游戏(2)

    HTML5 Canvas Game: 玩家飞船  本系列博文翻译自以下文章 http://blog.sklambert.com/html5-canvas-game-the-player-ship/ L ...

  3. Hive使用简介

    ---恢复内容开始--- 指定分隔符 HIVE输出到文件的分隔符 ,列与列之间是'\1'(ASCII码1,在vim里显示为^A),列内部随着层数增加,分隔符依次为'\2','\3','\4'等. 例: ...

  4. display:table合并表格

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  5. 配置git账号和密码

    最开始启动的时候 配置用户名和用户邮箱,安装完git第一件要做的事情! git config --global uesr.name "Sunnshino" git config - ...

  6. mysql 5.6 修改root原始密码不为空方法

    mysql 5.6安装好之后,是默认root用户的密码为空的,此时为了安全性需要修改密码不为空,修改方法为: cmd或者mysql 5.6 command line client登陆之后,输入一下命令 ...

  7. [Unity3D]查看与设置游戏帧数FPS

    原地址:http://blog.sina.com.cn/s/blog_5b6cb9500101bta4.html 关于FPS,在PC端来说,游戏帧数跑得越高越好,FPS跑得越高游戏就越流畅,当然太高也 ...

  8. Android开发之Is Library篇

    一.生活场景描述 由于公司有一个项目开发的时间比较长,项目里堆砌的代码也比较多,并且有些功能在给不同客户发布的时候有些功能还不需要,这样功能模块分离就很有必要了. 所以,Library就被推到了前台, ...

  9. 【DB2】报错:-30090 25000 指定的操作对远程执行失败

    场景描述: 数据库:DB_1,DB_2 现在在DB_1中建立NICKNAME为CST_INFO_NICK,并且该别名指向数据库DB_2的CST_INFO表,在DB_1中建立存储过程,该存储过程需要  ...

  10. Docker -CentOS 6.5上安装

    开始安装daoker之旅: 1. [root@localhost ~]# uname -r -.el6.x86_64 2. [root@localhost ~]# cat /etc/issue Cen ...