版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83119797
--------参考文献 W.Richard Stevens, Stephen A.Rago.UNIX环境高级编程[M].北京:人民邮电出版社,2014.6:190-192.
目录
一、引言
当一个进程正常或异常终止时,内核就向其父进程发送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 可以看到,SIGABRT的值为6,SIGCHLD的值为7,SIGFPE的值为8。这些数字都是用宏定义处理的幻数。