signal - asynchronous recycling mechanism

Preface: I used wait() and the non-blocking model before recycling the child process. After learning the signal today, the recycling mechanism can be improved to a higher level. Through the signal function, the parent process only needs to do its own thing, and it will be triggered after receiving the signal. signal function.

Possible bugs in signal handlers:

  1. The stop signal will also trigger the SIGCHLD signal, causing wait to block;

  2. After stopping, the signal will also be triggered, causing the parent process to block;

  3. Calling sigaction(), artificially sending a SIGCHLD signal will also block the parent process;

  4. Multiple processes end at the same time, which may cause incomplete recovery and generate zombie processes (the same signal is not queued);

The final code for the solution:

//Recycle subprocess asynchronously
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

#define NR 40

/*
 * Bugs: If multiple processes end at the same time, it may cause incomplete recycling and generate zombie processes (the same kind of signal is not queued)
 * The circular method waitpid solves the above bugs
*/
void waitChild(int signo)
{
     pid_t pid;
     printf("a sig recv:% d\n",signo);
     if(signo!=SIGCHLD) return;

     while(1) //Guaranteed to trigger a signal once and recycle all terminated child processes
     {
         pid=waitpid(-1,NULL,WNOHANG|WUNTRACED);/ /Guaranteed non-blocking, and stop does not trigger the signal
         printf("wait child:%d\n",pid);

         if(pid==0||pid==-1)
                break;
     }
}


int main(void)
{
     pid_t pid;

#if 0
     //The child process ends or stops or SIGCHLD signal occurs from stop to continue
     if(signal(SIGCHLD,waitChild)==SIG_ERR)
     {
         perror("signal");
         return 2;
     }
#else
     struct sigaction ac={.sa_handler=waitChild};//Handler function
     sigemptyset(&ac.sa_mask);//Do not expect to mask other signals
     ac.sa_flags=SA_NOCLDSTOP;//The SIGCHLD signal does not occur when the process stops
     sigaction(SIGCHLD,&ac,NULL) ;
#endif //

     int i;
     for(i=0;i<NR;i++)
     {
        pid=fork();
        if(pid==-1) return 1;//error
        else if(pid==0)/ /child
        {
            printf("%dth child <%d> start work.\n",i,getpid());
            sleep(3);
            printf("%dth child <%d> end   work.\n",i,getpid());
            exit(0);
        }
     }
     //parent
     while(1)
     {
         getchar();
         printf("parent working....\n");
     }

     return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324875995&siteId=291194637