c - Hanging loop with sleep() -


i'm trying learn how handle signals. in program have array of pids of earlier created subprocesess. no want every couple seconds send sigtstp signal 1 of them. have send sigchld parent process , exit. parent process should print exit code of exited process , create next 1 in place of exit one. works fine in first loop hangs in second. on output get:

loop slept forking in array loop zakonczyl sie potomek 3934 z kodem 0. 

so it's seems sleep works in first loop not in second. or main process didn't control after handling signal should't happen. have no idea whats may wrong here.

while(1) {                 printf("loop\n");                 sleep(5);                 printf("slept\n");                 int r = rand() % n;                 if(kill(process_tab[r],sigtstp) < 0) {                         printf("error while sending sigtstp signal.\n");                 } else {                         printf("forking\n");                         if((child = fork()) < 0) {                                 printf("fork failed.\n");                         } else if(child == 0) {//to sie dzieje w procesie                                 if(signal(sigtstp,&catch_sigtstp)) {                                         printf("error while setting signal handler.\n");                                         _exit(exit_failure);                                 }                                 while(1) {                                 }                         } else { //to sie dzieje w parencie                                 process_tab[r] = child;                                 printf("in array\n");                         }                 } } 

and here handlers.

void catch_sigtstp(int signal) {         kill(ppid,sigchld);         _exit(exit_success); }  void catch_sigchld (int signal) {         int status;         pid_t child = wait(&status);         printf("zakonczyl sie potomek %d z kodem %d.\n",child,status); } 

add fflush after printf.

printf("something\n"); fflush(stdout); 

otherwise may not output stdio buffered default.

edit: issues of handler

it pretty unsafe use printf function in signal handler, not reentrant. also, catch_sigchild function can modified:

void catch_sigchld (int signal) {     int status;     pid_t child;      while ((child = waitpid(-1, &status, wnohang)) > 0)     {        // may else?        // ...printf("zakonczyl sie potomek %d z kodem %d.\n",child,status);      } }    

the reason 1 signal can delivered multiple dead children.

edit: blocking signal when printing.

to avoid deadlock inside stdio, should block signal:

sigset_t set;  sigemptyset(&set); sigaddset(&set, sigchild);  ... sigprocmask(sig_block, &set, null); printf("my output"); sigprocmask(sig_unblock, &set, null); ... 

edit: @barmar has pointed, parent process receive sigchild signal twice: once child'd signal handler, , 1 os.

to fix, might sufficient remove own signal source:

void catch_sigtstp(int signal) {     // kill(ppid,sigchld); //< 1 causes 2 signals per 1 child     _exit(exit_success); } 

Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -