0

There's my test code below. I expect the output should print out all the child processes created before parent process terminates, but it does not. Please tell me why.

In the test code, it creates 10 processes and waits for them again and again. I want the program to run on the condition that I have at most 10 processes at the same time. My platform is Linux.

//#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wait.h>
//using namespace std;
void sig_chld(int signo)
{ 
    pid_t pid;
    int stat;
    pid=wait(&stat);
    fprintf(stderr, "child [%d] terminate\n",pid);          
    return;
}
int main(){ 
    signal(SIGCHLD,sig_chld);
    pid_t PID,old;
    for(int i=0;i<1000;i++){

        fprintf(stderr, "i == %d\n",i); 
        PID = fork();       
        switch(PID){
                case -1:
                    fprintf(stderr, "fork fail");   
                break;
                case 0:
                    exit(0);
                break;
                default:
                    if(i==0)old=PID;
                    if(i%100==99){      
                        fprintf(stderr, "start waiting child [%d] with i = %d   --------------------\n",old,i); 
                        waitpid(old,NULL,0);
                                
                        old = PID;
                    }
                    fprintf(stderr, "child [%d] create\n",PID);             
        }
    }
    fprintf(stderr, "final waiting for [%d] \n",PID);
    waitpid(PID,NULL,0);
    fprintf(stderr, "parent end\n");

    return 0;
}

Below are the last few lines of the output. There are still a lot processes that don't terminate.

i == 992
child [13805] create
i == 993
child [13806] create
i == 994
child [13636] terminate
child [13637] terminate
child [13640] terminate
child [13810] create
i == 995
child [13811] create
i == 996
child [13812] create
i == 997
child [13642] terminate
child [13643] terminate
child [13814] create
i == 998
child [13645] terminate
child [13646] terminate
child [13816] create
i == 999
start waiting child [13666] with i = 999   --------------------
child [13817] create
final waiting for [13817]
child [13647] terminate
child [13648] terminate
child [13649] terminate
parent end
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    This is a very bad idea to output to the console from the signal handler. This is the root issue in that code. The next a very bad idea is wait in the signal handler. – 273K Oct 19 '21 at 17:58
  • The list of [things you can do in a signal handler](https://man7.org/linux/man-pages/man7/signal-safety.7.html) is much shorter than the list of things you can't. – user4581301 Oct 19 '21 at 18:26
  • I think you should remove the [tag:c++] tag; the only C++ lines here are an unused `#include` and an unnecessary `using`, and none of that is relevant to the question. Neither `fprintf` nor `std:iostream` can be used in a signal handler but I don't believe that error is relevant either. – rici Oct 19 '21 at 21:53
  • The POSIX header for `waitpid()` et al is `` rather than ``. It probably doesn't matter, but it is as well to be consistent. – Jonathan Leffler Oct 20 '21 at 04:09
  • Since you're using `signal()` rather than `sigaction()`, there's at least some chance that your code is missing some `SIGCHLD` signals. You don't appear to be making any attempt to limit the number of children to 10 concurrently running. You might want to have the children sleep different random times (which isn't wholly trivial to achieve — they have the same state as the parent), so that you can see that you're handling the different delays correctly. – Jonathan Leffler Oct 20 '21 at 04:12
  • See [SO 1974-7644 — Shell: run 4 processes in parallel](https://stackoverflow.com/q/19747644/15168) for Perl logic which does what you're trying to do. It shouldn't be very hard to convert that to C. See also [How to avoid using `printf()` in a signal handler?](https://stackoverflow.com/q/16891019/15168). – Jonathan Leffler Oct 20 '21 at 04:34

0 Answers0