wait和waitpid出現的原因
SIGCHLD
--當子進程退出的時候,內核會向父進程SIGCHLD信號,子進程的退出是個異步事件(子進程可以在父進程運行的任何時刻終止)
--子進程退出時,內核將子進程置為僵屍狀態,這個進程成為僵屍進程,它只保留最小的一些內核數據結構,以便父進程查詢子進程的退出狀態
--父進程查詢子進程的退出狀態可以用wait/waitpid函數
wait獲取staus后檢測處理
宏定義 描述
WIFEXITED(status) 如果進程子進程正常結束,返回一個非零值
WEXITSTATUS(status) 如果WIFEXITED非零,返回子進程退出碼
WIFSIGNALED(status) 子進程因為捕獲信號而終止,返回非零值
WTERMSIG(status) 如果WIFSIGNALED非零,返回信號代碼
WIFSTOPPED(status) 如果進程被暫停,返回一個非零值
WSTOPSIG(status) 如果WIFSTOPPED非零,返回信號代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int arg,char *args[])
{
pid_t pid=fork();
if(pid==-1)
{
printf("fork() failed ! error message:%s\n",strerror(errno));
return -1;
}
if(pid>0)
{
int status=0;
printf("父進程\n");
wait(&status);
if(WIFEXITED(status))//WIFEXITED宏的釋義: wait if exit ed
{
printf("子進程返回信息碼:%d\n",WEXITSTATUS(status));
}else if(WIFSIGNALED(status))
{
printf("子進程信號中斷返回信息碼:%d\n",WTERMSIG(status));
}else if(WIFSTOPPED(status))
{
printf("子進程暫停返回信息碼:%d\n",WSTOPSIG(status));
}else
{
printf("其他退出信息!\n");
}
}else if(pid==0)
{
printf("i am child !\n");
abort();
//exit(100);
}
printf("game is over!\n");
return 0;
}
wait()函數成功返回等待子進程的pid,失敗返回-1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int arg, char *args[])
{
pid_t pid = 0;
int i = 0, ret = 0;
for (i = 0; i < 10; i++)
{
pid = fork();
if (pid == -1)
{
printf("fork() failed ! error message:%s\n", strerror(errno));
return -1;
}
if (pid == 0)
{
printf("child haved run!\n");
exit(0);
}
}
while (1)
{
//wait()函數的返回值是子進程的pid
ret = wait(NULL);
printf("子進程pid=%d\n", ret);
if (ret == -1)
{
//父進程wait()函數阻塞過程中,有可能被別的信號中斷,需要做異常處理
if (errno == EINTR)
{
continue;
}
break;
}
}
printf("game is over!\n");
return 0;
}
waitpid
函數功能:用來等待某個特定進程的結束
函數原型:
pid_t waitpid(pid_t pid, int *status, int options);
參數:
status如果不為空,會把狀態信息寫到它指向的位置
options允許改變waitpid的行為,最有用的一個選項是WNOHANG,它的作用是防止waitpid把調用者的執行掛起
返回值:成功返回等待子進程的pid,失敗返回-1