函数wait和waitpid

版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83119797

                 --------参考文献   W.Richard Stevens, Stephen A.Rago.UNIX环境高级编程[M].北京:人民邮电出版社,2014.6:190-192.

目录

一、引言 

二、 打印exit状态的说明

三、 测试用例


一、引言 

当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。因为子进程的终止是一个异步事件,所以这种信号也是内核向父进程发的异步通知

现在需要知道的是调用wait或者waitpid的进程可能会发生什么。

  • 如果其所有进程都还在运行,则阻塞。
  • 如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。
  • 如果它没有任何子进程,则立即出错返回。

如果进程由于接收到SIGCHLD信号而调用wait,我们希望wait会立即返回。但是如果在随机时间调用wait,则进程可能会阻塞。

#include<sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);

返回值类型:成功返回进程ID;出错返回0或-1。小技巧——为了使函数能够一次返回两种值,可以通过函数形参列表将值带回


二、 打印exit状态的说明

使用宏以打印进程终止状态的说明——子进程因何而终止:正常终止(WIFEXIT)?异常终止(WIFSIGNALED)(浮点错误:除数为0等)?仅暂停(WIFSTOPPED)?暂停后继续(WIFCONTINUED)?

#include<sys/wait.h>
#include<stdio.h>

void
pr_exit(int status){
    if(WIFEXITED(status))    //正常终止,转调宏WEXITSTATUS
        printf("normal termination, exit status = %d\n",
                WEXITSTATUS(status));

    else if(WIFSIGNALED(status))    //异常终止。转调宏WTERMSIG,如果定义了宏WCOREDUMP
        printf("abnormal termination, signal number = %d%s\n",
                WTERMSIG(status),
#ifdef WCOREDUMP    //如果已经定义了宏WCOREDUMP,还需调用宏WCOREDUMP
            WCOREDUMP(status) ? "(core file generated)" : "");
#else 
            "");
#endif
    else if(WIFSTOPPED(status))      //暂停子进程返回的状态                                           
        printf("child stopped, signal number = %d\n",
                WSTOPSIG(status));
}

三、 测试用例

#include<sys/wait.h>
#include<stdio.h>   //printf()
#include<stdlib.h>  //abort()

int main(){
    pid_t pid;
    int status;

    pid = fork();        //子进程模拟的状态是正常结束
    if(pid < 0)
        printf("fork error!\n");
    else if(0 == pid)   //chld
        exit(7);
    if(wait(&status) != pid)    //wait for chld and pr its status
        printf("wait error!\n");
    pr_exit(status); 

    pid = fork();        //子进程模拟的状态是异常结束
    if(pid < 0)
        printf("fork error!\n");                                                
    else if(0 == pid)   //chld
        abort();
    if(wait(&status) != pid)    //wait for chld and pr its status
        printf("wait error!\n");
    pr_exit(status);

    pid = fork();        //子进程模拟的状态是浮点错误(除数为0)
    if(pid  < 0)    //chld
        printf("fork error!\n");
    else if(pid == 0)       //wait for chld and pr its status
        status /= 0;
    if(wait(&status) != pid)
        printf("wait error!\n");
    pr_exit(status);

    exit(0);
}  
图1 Linux下运行结果

从图1 可以看到,SIGABRT的值为6,SIGCHLD的值为7,SIGFPE的值为8。这些数字都是用宏定义处理的幻数

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/83119797
今日推荐