如何向 child 多次发送信号以避免僵尸状态? C语言

How to send a signal to a child several times avoiding zombie state? C language

我需要向 child 进程发送信号 3 次。

问题是child只收到一次信号就变成了僵尸

预期输出为:

我是 child 11385,我收到了 SIGUSR1

我是 child 11385,我收到了 SIGUSR1

我是 child 11385,我收到了 SIGUSR1

但实际输出是:

我是 child 11385,我收到了 SIGUSR1

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

void my_handler()
{
  printf("\n I'm the child %i and i received SIGUSR1\n", getpid());
}


int main (int argc, char **argv) {
    int *array;
    int N = 10;
    int i;
    pid_t pid1;
    array=(int*)malloc(sizeof(int)*N);


    signal(SIGUSR1,my_handler);

    for (i = 0; i< N; i++) 
    {
        pid1 = fork();
        if(pid1 < 0)
        {
            exit(EXIT_FAILURE);
        }
        else if (pid1 > 0)
        {
            array[i]= pid1;
        }

        else
        {   
            sleep(100);
            exit(EXIT_SUCCESS);
        }
    }

    i=0;
    while(i<3) // I need to call the son 3 times
    {
        kill(array[1], SIGUSR1);
        i++;
    }
}

当child接收到信号时,它可能正在等待sleep终止。即使时间尚未到期,第一个信号也会中断 sleep,导致 return,errno 设置为 EINTR。如果你想让它一直休眠,你需要再次调用sleep

  • 你的父进程没有等待子进程就退出了
  • 信号可以发送的很快,我加了一个小延迟
  • 我添加了更多延迟
  • 信号处理程序的正确签名是void handler(int signum)这很重要,因为处理程序是使用参数调用的,并且信号处理程序的堆栈布局不同。
  • 您不应该从信号处理程序调用 printf(),它不是异步安全的。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

char pidstr[10];
char massage[]="        I'm the child and i received SIGUSR1\n";

#define CNT 1
void my_handler(int signum)
{
write(0, massage, strlen(massage));
}


int main (int argc, char **argv) {
    int i , err, status;
    pid_t pid1;
    int array[CNT];

    signal(SIGUSR1, my_handler);

    for (i = 0; i< CNT; i++) {
        pid1 = fork();
        if(pid1 < 0) { exit(EXIT_FAILURE); }
        else if (pid1 > 0) {
                printf("ChildPid=%d\n", pid1 );
            array[i]= pid1;
        }

        else
        {   // child
                // signal(SIGUSR1, my_handler);
            sprintf(pidstr,"[%d]", getpid() );
            memcpy (massage,pidstr, strlen(pidstr));
            sleep(10);
                printf("Unslept\n");
            sleep(10);
                printf("Unslept\n");
            sleep(10);
                printf("Unslept\n");
            exit(EXIT_SUCCESS);
        }
    }
    sleep(10);
    for (i=0; i<3; i++) {
        err = kill(array[0], SIGUSR1);
        printf("Err=%d:%d\n", err, (err) ? errno: 0 );
        sleep(1);
    }

    while ( (pid1=wait( &status)) != -1){
        printf("[Parent] Reaped %d\n", pid1);
        }

return 0;
}