进程 子进程 关系

父子进程

1. 退出关系

  • 子进程继承了父进程的内容
  • 父子进程有独立的地址空间, 互不影响

若父进程先结束
子进程成为孤儿进程,被init进程收养 ——》 子进程变成后台进程
若子进程先结束 ——》 父进程如果没有及时回收,子进程变成僵尸进程

2. 执行位置

fork 创建了子进程后,子进程从何处执行?
子进程从fork的下一条语句开始执行
父子进程谁先执行?
不确定,看操作系统先调度谁

3. 进程回收函数 —— wait

#include <unistd.h>
pid_t wait(int * status);

成功时返回回收的子进程的进程号;失败时返回EOF
若子进程没有结束,父进程一直阻塞
若有多个子进程,哪个子进程先结束就先回收
(有多少个子进程,就应该有多少个wait)
status 指定保存子进程返回值和结束方式的地址
statusNull, 直接释放子进程PCB,不接收返回值

int void main(int argc, const char * argv[])
{
    int status;
    pid_t pid;
    
    if((pid ==fork()) < 0){
    	perror("fork");exit(-1);
    }else if(0 == pid){
    	sleep(1);exit(2);
    }else{
    	wait(&status);
    	printf("%x
", status);
    }
}

进程返回值和结束方式
子进程通过exit/_exit/return 返回某个值(0-255)
父进程调用wait(&status)回收
WIFEXITED(status) //判断子进程是否正常结束
WEXITSTATUS(status) 获取子进程返回值
WIFSIGNALEN(status) 判断子进程是否被信号结束
WTERMSIG(status) 获取结束子进程的信号类型

status[15: 0]
[6:0]为0 表示正常结束
      大于0 表示结束子进程的信号类型
 [15:8] 子进程返回值

进程回收函数 —— waitpid

#include<unistd.h>
pid_t waitpid(pid_t pid, int * status, int option);

成功时返回回收的子进程的pid或0;失败时返回EOF
pid 可用于指定回收哪个子进程或任意子进程
status 制定用于保存子进程返回值和结束方式的地址
option指定回收方式,0或WNOHANG

eg: waitpid(pid, &status, 0);

以阻塞方式回收指定子进程

waitpid(pid, &status, WNOHANG);

以非阻塞方式回收指定子进程(子进程没有结束返回0)

waitpid(-1, &status, 0) 等价于wait
waitpid(-1,&status, WNOHANG);

进程结束 exit / _exit

#include <stdlib.h> 
#include <unistd.h>
void exit(int status);   stdlib.h
void _exit(int status);

结束当前的进程并将status 返回
exit结束时会刷新(流)缓冲区


exec函数族

进程调用exec函数族执行某个程序,进程当前内容被指定的程序替换
实现让父子进程执行不同的程序

  1. 父进程创建子进程
  2. 子进程调用exec函数族
  3. 父进程不受影响
    应用举例: shell
#include <unistd.h>
int execl(const char *path, const char * arg, ...);
int execlp(const char *file, const char * arg, ...);

成功时执行指定的程序; 失败时返回EOF
path 执行的程序的名称, 包含路径
arg... 传递给执行程序的参数列表
file 执行的程序的名称,在PATH中查找

eg: if(execl("/bin/ls", "ls","-a", "-l", "/etc", NULL )<0)
{
	perror("execl");
}

if(execlp("ls", "ls","-a", "-l", "/etc", NULL )<0)
{
	perror("execl");
}
int execv(const char * path,  char * const argv[] );
int execvp(const char * file,  char * const argv[] );
//成功时执行指定的程序; 失败时返回EOF

eg;char * arg[] = {"ls", "-a", "-l", "/etc",NULL};
if(execv("bin/ls", arg) < 0)
{
	perror(execv);
}

if(execv("ls", arg) < 0)
{
	perror(execvp);
}

system

#include <stdlib.h>
int system(const char * command);

调用此进程先创建子进程,执行完后返回当前进程
成功时返回command的返回值, 失败时返回EOF
当前进程等待command执行结束后才继续执行

原文地址:https://www.cnblogs.com/fengyang66/p/6143013.html