WEXITSTATUS与WIFEXITED
wait()的函数原型是:
#include
#include
pid_t wait(int *status)
进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样: pid = wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。
WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。
WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。
#include
#include
#include
#include
#include
void f(){
printf("THIS MESSAGE WAS SENT BY PARENT PROCESS..\n");
}
main(){ int i,childid,status=1,c=1; signal(SIGUSR1,f); //setup the signal value i=fork(); //better if it was: while((i=fork)==-1); if (i){ printf("Parent: This is the PARENT ID == %d\n",getpid()); sleep(3); printf("Parent: Sending signal..\n"); kill(i,SIGUSR1); //send the signal
//status is the return code of the child process wait(&status); printf("Parent is over..status == %d\n",status);
//WIFEXITED return non-zero if child exited normally printf("Parent: WIFEXITED(status) == %d\n",WIFEXITED(status));
//WEXITSTATUS get the return code printf("Parent: The return code WEXITSTATUS(status) == %d\n",WEXITSTATUS(status)); } else { printf("Child: This is the CHILD ID == %d\n",getpid()); while(c<5){ sleep(1); printf("CHLID TIMER: %d\n",c); c++; } printf("Child is over..\n"); exit(2); } }
输出: Child: This is the CHILD ID == 8158 Parent: This is the PARENT ID == 8157 CHLID TIMER: 1 CHLID TIMER: 2 Parent: Sending signal.. THIS MESSAGE WAS SENT BY PARENT PROCESS.. CHLID TIMER: 3 CHLID TIMER: 4 Child is over.. Parent is over..status == 512 Parent: WIFEXITED(status) == 1 //正常退出 Parent: The return code WEXITSTATUS(status) == 2 //拿到子进程返回值
进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样: pid = wait(NULL);
如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。
WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。
WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。
#include
main(){ int i,childid,status=1,c=1; signal(SIGUSR1,f); //setup the signal value i=fork(); //better if it was: while((i=fork)==-1); if (i){ printf("Parent: This is the PARENT ID == %d\n",getpid()); sleep(3); printf("Parent: Sending signal..\n"); kill(i,SIGUSR1); //send the signal
//status is the return code of the child process wait(&status); printf("Parent is over..status == %d\n",status);
//WIFEXITED return non-zero if child exited normally printf("Parent: WIFEXITED(status) == %d\n",WIFEXITED(status));
//WEXITSTATUS get the return code printf("Parent: The return code WEXITSTATUS(status) == %d\n",WEXITSTATUS(status)); } else { printf("Child: This is the CHILD ID == %d\n",getpid()); while(c<5){ sleep(1); printf("CHLID TIMER: %d\n",c); c++; } printf("Child is over..\n"); exit(2); } }
输出: Child: This is the CHILD ID == 8158 Parent: This is the PARENT ID == 8157 CHLID TIMER: 1 CHLID TIMER: 2 Parent: Sending signal.. THIS MESSAGE WAS SENT BY PARENT PROCESS.. CHLID TIMER: 3 CHLID TIMER: 4 Child is over.. Parent is over..status == 512 Parent: WIFEXITED(status) == 1 //正常退出 Parent: The return code WEXITSTATUS(status) == 2 //拿到子进程返回值