Linux--exit,on_exit,wait,waitpid,函数的使用

回收进程资源

exit(0) _exit(0);
return

      int on_exit(void (*function)(int , void *), void *arg);

on_exit 在退出的时候可以绑定一个回调函数,在退出的时候调用回调函数

#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>

int g_val = 0;

void test_exit(int status,void *arg)
{
	printf("befor exit\n");
	printf("exit %d\n",status);
	printf("arg=%s \n",(char *)arg);
}
int main()
{
    pid_t id = fork();
    if(id < 0){
        exit(1);
    }
    else if(id == 0){
        //child
        printf("child is run,child pid is %d\n",getpid());
        sleep(1);
		char *str="test";
		on_exit(test_exit,(void*)str);
        exit(100);
    }
    else{
        printf("father is run , father pid is: %d\n",getpid());
    }

    int ret;
    if(wait(&ret) < 0){
        printf("wait error , error code is : %d\n",errno);
        return 1;
    }
    printf("wait success,status code is : %d\n",WIFEXITED(ret));
    return 0;
}

运行效果
在这里插入图片描述

在exit的时候会调用fflush函数

一个进程在使用exit _exit return 退出的时候,只是灵魂性的退出,而肉体并没有退出,那么我们如何把内核中的肉体,也就是内核中task_struct结构体清掉呢?

子进程的肉体也叫僵尸进程

那么父进程就要使用wait和waitpid函数进行清除内核中的task_struct结构体

       pid_t wait(int *wstatus);

       pid_t waitpid(pid_t pid, int *wstatus, int options);

waitpid 的返回值是: 退出的子进程的pid

wstatus: 子进程的退出码(也就是子进程中exit括号中填的参数)

options: 表示阻塞或非阻塞(阻塞:填0 非阻塞:WNOHANG)

pid_t pid:

扫描二维码关注公众号,回复: 11484293 查看本文章

pid>0 : 指定等待哪个子进程

​ pid=-1 :表示等待任意子进程结束

​ pid = 0 : 表示等待与当前进程的gpid相同的任意一个进程结束

​ pid< -1 : (例如:-2)等待组ID为2的任意一个子进程

  • 阻塞wait
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<sys/wait.h>

int main()
{
    pid_t pid;
    pid = fork();
    if(pid < 0){
        printf(" fork error: %d \n",errno);
        return 1;
    }
    else if(pid == 0){
            //child
            printf("I am child..pid is :%d\n",getpid());
            sleep(5);
            exit(23);
    }
    else{
            int status = 0;
            pid_t ret =waitpid(-1,&status,0);//blocking waiting for 5S
            printf("this is test for wait\n");
            if(WIFEXITED(status) && ret == pid){
               printf("wait child 5S success,child return code is:%d.\n",WEXITSTATUS(status));
            }else{
                printf("wait child failed.return \n");
                return 1;
        }
    }
    return 0;
}

运行结果
在这里插入图片描述

  • 非阻塞waitpid
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<errno.h>

int main()
{
    pid_t pid;
    pid = fork();
    if(pid < 0){
        printf("fork error: %d \n",errno);
        return 1;
    }
    else if(pid == 0){
        printf("child is run .pid id : %d\n",getpid());
        sleep(5);
        exit(1);
    }
    else{
        int status = 0;
        pid_t ret = 0;
        do{
            ret = waitpid(-1,&status,WNOHANG);//非阻塞等待
            if(ret == 0){
                printf("child is running\n");
            }
            sleep(1);
    }while(ret == 0);
        if(WIFEXITED(status) && ret == pid){
            printf("wait child 5s  success,child return code is :%d\n",WEXITSTATUS(status));
        }else{
            printf("wait child failed,return.\n");
            return 1;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45309916/article/details/107582591