子進程的異步等待方式

一.SIGCHLD

   SIGCHLD信號:當子進程退出時,它會向父進程發送SIGCHLD信號,該信號的默認處理方式爲忽略,當父進程以阻塞方式等待時,它不能處理自己的工作。
   我們自定義一個捕捉信號的函數catchsig。

代碼如下:

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

void catchsig(int sig)
{
   printf("get a sig:%d,pid:%d\n",sig,getpid());
}

int main()
{
   signal(SIGCHLD,catchsig);
   pid_t id=fork();
   if(id==0)
   {//child
      printf("I am child,quit! pid:%d\n",getpid());
      exit(1);
   }
   else
   {//father
     waitpid(id,NULL,0);//以阻塞方式等待
   }
   return 0;
}

結果如圖所示:
這裏寫圖片描述

子進程退出,向父進程發送信SIGCHLD,父進程會調用SIGCHLD的捕捉函數。

二. 父進程等待子進程的異步方式

    父進程自定義SIGCHLD信號的處理函數,並採用非阻塞方式等待,當子進程退出時,會向父進程發送信號,父進程會進行回收。
    當有10個子進程退出時,會給父進程發送10個信號,但由於只會記錄一次,所以只能回收一次,我們讓父進程一直回收,當子進程全部被回收完時,waitpid()會出錯返回。

代碼如下:

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

void catchsig(int sig)
{
   do
   {
      pid_t ret=waitpid(-1,NULL,WNOHANG);//-1表示可以回收任何進程,WNOHANG表示非阻塞方式等待
      if(ret>0)
      {
         printf("wait success:%d\n",ret);
      }
      else
      {
         printf("wait filed:%d\n",ret);
         break;
      }
   }while(1);
}

int main()
{
   signal(SIGCHLD,catchsig);
   pid_t id=fork();
   if(id==0)
   {//child
      printf("I am child,quit! pid:%d\n",getpid());
      exit(1);
   }
   else
   {//father
      while(1)
      {
          printf("do father things!\n");
          sleep(1);
      }
   }
   return 0;
}

結果如下:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章