目录
void _exit(int status)与void exit(int status)的不同
void waitpid(pid_t, int* status, int options)
进程终止
进程终止就是退出一个进程
进程退出的三个场景
1:正常退出,结果符合预期
2:正常退出,结果不符合预期结果
3:异常退出
进程中退出的方式
1:在main函数中return,退出进程
2:void _exit(int status),退出进程
3:void _exit(int status),退出进程
void _exit(int status)与void exit(int status)的不同
void _exit(int status)是系统调用接口,退出进程时不会刷新缓冲区,直接释放资源
void exit(int status)是库函数,退出进程时会刷新缓冲区
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void func()
{
printf("lbwnb\n");
sleep(3);
_exit(0);//不会打印
// exit(0) 会打印 lbwnb
}
int main()
{
func();
return 0;
}
status时退出的返回值,它的作用等会在进程等待中再讲
进程等待
进程等待的作用
进程等待时为了避免僵尸进程的产生,僵尸进程就是处于退出状态的进程,但是资源没有得到完全释放,产生僵尸进程的原因是因为子进程先于父进程退出,而父进程没有获取子进程的退出信息,则该子进程就成为僵尸进程
为了避免这种情况,父进程等待子进程退出,获取子进程的推出信息,释放子进程资源,避免产生僵尸进程
pid_t wait(int * status)
阻塞等待任意一个子进程的退出,通过status获取子进程的退出返回值,pit_d wait(int* status)的返回值为子进程的该pid
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
pid_t pid = fork();
if(0 == pid)
{
sleep(3);
exit(0);
}
sleep(10);//为了方便观察进程的状态
int status;
wait(&status)
//只有父进程才能走下来
while(1)
{
printf("-------\n");
}
return 0;
}
我们在上面提到过wait(int* status)等待任意一个子进程的退出,那么就是说wait不仅仅处理的是刚刚退出的进程,只要是在调用子进程退出,wait都会获取子进程的退出返回值,释放资源
void waitpid(pid_t, int* status, int options)
参数的说明:
pid_t: 值为-1表示等待任意一个进程的退出
status:进程退出的返回值
options: 值为0则阻塞等待子进程的退出,waitpid( -1, &status, 0) == wait( &status) / 当值为WNOHONG---将waitpid设置为非阻塞
waitpid的返回值:-1 表示出错; 0 表示没有子进程退出; >0表示又子进程退出,退出的子进程pid就是它的返回值
阻塞与非阻塞
阻塞:为了完成功能,发起调用,若当前不具备完成完成功能的条件,则一直等待
非阻塞:为了完成功能,发起调用,若当前不具备完成功能的条件,则直接报错
status
用wait和waitpia获取status的返回值是,要注意 : status有四个字节,但是前十六个字节未使用;返回值放在低十六位中的高八位
因此status的返回值获取:(status>>8)&0xff ( &0xff 只是为了取得低八位)
进程的退出场景大致分为两种: 正常退出和异常退出 ,若异常退出则此时进程退出的返回值是不可信的,因此在获取进程退出的返回值时,应该先判断进程是否时正常推出的
判断进程是否正常退出
进程是否正常退出的信息存放在status的低七位中, 低七位为0 则表示进程正常退出,反之异常退出
因此获取status中进程是否正常退出信息: status & 0x7f