wait获取子进程退出状态 WIFEXITED和WIFSIGNALED用法

可以使用wait函数传出参数status来保存进程的退出状态


常用宏函数分为日如下几组:
1、 WIFEXITED(status) 若此值为非0 表明进程正常结束。
若上宏为真,此时可通过WEXITSTATUS(status)获取进程退出状态(exit时参数)
示例:

        if(WIFEXITED(status)){
            printf("退出值为 %d\n", WEXITSTATUS(status));
        }

2、 WIFSIGNALED(status)为非0 表明进程异常终止。
若上宏为真,此时可通过WTERMSIG(status)获取使得进程退出的信号编号
用法示例:

    if(WIFSIGNALED(status)){
        printf("使得进程终止的信号编号: %d\n",WTERMSIG(status));   
    }

3、 WIFSTOPPED(status)为非0 表明进程处于暂停状态
若上宏为真,此时可通过WSTOPSIG(status)获取使得进程暂停的信号编号
4、 WIFCONTINUED(status) 非0表示暂停后已经继续运行。


WIFEXITED和WIFSIGNALED用法完整程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
    pid_t pid, wpid;
    int status;

    pid = fork();
    if(pid == 0){               //子进程
        printf("child --- my parent is %d\n", getppid());
        sleep(30);              //子进程睡眠30秒
        printf("child is die\n");
     }else if(pid>0){           //父进程
        wpid = wait(&status);   //等待回收子进程
        if(wpid == -1){
            perror("wait error:");
            exit(1);
        }
        //正常退出判断
        if(WIFEXITED(status)){
            printf("child exit with %d\n", WEXITSTATUS(status));
        }

        //因为某种信号中断获取状态
        if(WIFSIGNALED(status)){
            printf("child killed by %d\n", WTERMSIG(status));
        }

        while(1)
        {
            printf("parent pid = %d, sonpid = %d\n", getpid(), pid);
            sleep(1);
        }
        } else {
            perror("for error");
            exit(1);
        }

    return 0;
}

测试程序
编译程序:

yu@ubuntu:~/cplusplus/wait进程控制$ gcc getstatus.c -o getstatus.out

1、首先测试WIFEXITED正常退出情况,执行:

yu@ubuntu:~/cplusplus/wait进程控制$ ./getstatus.out 
child --- my parent is 6408
child is die
child exit with 0
parent pid = 6408, sonpid = 6409
parent pid = 6408, sonpid = 6409
parent pid = 6408, sonpid = 6409
parent pid = 6408, sonpid = 6409
....

2、测试WIFSIGNALED信号终止,执行(sleep(300)便于测试):

yu@ubuntu:~/cplusplus/wait进程控制$ ./getstatus.out 
child --- my parent is 6418

此时另开一终端,查看进程,kill命令终止子进程:

yu@ubuntu:~/cplusplus/Process$ ps aux | grep getstatus.out
yu         6437  0.0  0.0   4224   784 pts/18   S+   21:58   0:00 ./getstatus.out
yu         6438  0.0  0.0   4356    84 pts/18   S+   21:58   0:00 ./getstatus.out
yu         6442  0.0  0.0  21292   976 pts/4    S+   21:58   0:00 grep --color=auto getstatus.out

yu@ubuntu:~/cplusplus/Process$ kill 6438

此时子进程异常终止,getstatus.out 程序输出信息:

yu@ubuntu:~/cplusplus/wait进程控制$ ./getstatus.out 
child --- my parent is 6437
child killed by 15
parent pid = 6437, sonpid = 6438
parent pid = 6437, sonpid = 6438
parent pid = 6437, sonpid = 6438
parent pid = 6437, sonpid = 6438
...

如上所知,使得进程终止的信号编号为15,通过 kill –l可知15号信号为SIGTERM:

yu@ubuntu:~/cplusplus/wait进程控制$ kill -l
 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP
 6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR
31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX    
waitpid函数可以用于等待一个特定的子进程或等待任何一个子进程。如果使用waitpid等待一个特定的子进程,需要传递该子进程的PID作为参数。如果使用waitpid等待任何一个子进程,则只需要将pid参数设置为-1即可。 以下是一个使用waitpid函数等待子进程状态的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 printf("子进程正在运行...\n"); sleep(5); printf("子进程结束\n"); exit(0); } else if (pid > 0) { // 父进程 int status; pid_t child_pid; do { child_pid = waitpid(pid, &status, WUNTRACED | WCONTINUED); if (child_pid == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("子进程 %d 正常结束,退出状态码 %d\n", child_pid, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("子进程 %d 被某个信号终止,终止信号 %d\n", child_pid, WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("子进程 %d 被某个信号停止,停止信号 %d\n", child_pid, WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("子进程 %d 被继续执行\n", child_pid); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); printf("父进程结束\n"); exit(EXIT_SUCCESS); } else { perror("fork"); exit(EXIT_FAILURE); } } ``` 在上面的代码中,当父进程调用waitpid函数等待子进程时,它会不断轮询子进程状态,直到子进程正常结束、被信号终止或被信号停止。根据不同的状态,父进程会打印不同的信息。当子进程结束后,父进程也会结束。 注意,waitpid函数会阻塞父进程,直到子进程状态发生改变。如果父进程不希望阻塞,可以将options参数设置为WNOHANG,这样waitpid函数会立即返回,如果没有任何子进程状态发生改变,返回值为0。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值