为什么我的第一个子进程没有收到父母发出的信号

0 c linux fork signals

这个程序已经用C编写并在ubuntu上编译.我的脚本创建了两个孩子.第一个记录他的pid在静态变量.创建第二个孩子并向父母发送信号.

父母接收信号并在此回合向第一个孩子发送信号.但是第一个孩子没有收到这个信号.从不调用函数sig_handlerr.

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <time.h>
# include <signal.h>
# include <sys/mman.h>

static pid_t* pidt;

// handler signal père
void sig_handler(int signo)
{   
  if (signo == SIGUSR1) {
    printf("SIG HANDLER received SIGUSR1 by process %d\n", getpid());
    printf("-> Envoie du signal SIGUSR1 au fils %d\n", pidt[0]);
    // le père envoie un signal au premier fils
    kill(pidt[0], SIGUSR1);
  }

}
// handler signal fils
void sig_handlerr(int signo)
{   
  if (signo == SIGUSR1) {
    printf("SIG HANDLER2 received SIGUSR1 by process %d\n", getpid());
  }

}

int main(int argc, char* argv[]) {

    printf("pid du processus père %d\n", getpid());

    pidt = mmap(NULL, sizeof(pid_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    if (fork()==0) {    
        printf("1 processus fils %d\n", getpid());
        pidt[0]=getpid();
        printf("pid enregistré= %d\n", pidt[0]);
        signal(SIGUSR1, sig_handlerr);
        exit(0);
    }
    wait(NULL); 

    signal(SIGUSR1, sig_handler);

    if (fork()==0) {
        printf("2 processus fils %d", getpid());

        // il envoie un signal SIGUSR1 au processsu père
        printf("-> envoie SIGUSR1 au père %d\n", getppid());
        kill(getppid(), SIGUSR1); // envoie un signal SIGUSR1 au processus père
        exit(0);
    }
    wait(NULL);

    printf("\n\n------ Fin du programme -------");
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

你可以解释一下为什么好吗?

zwo*_*wol 6

你有很多错误,其中最重要的是:

  • 您的第一个子进程在调用后立即退出signal,并且父进程在开始第二个进程之前等待它.这意味着,当父母到处向第一个孩子发送信号时,第一个孩子不再在那里接收它.使用sigsuspend让家长和第一个孩子的睡眠,直到信号到达,并呼吁wait其他所有工作完成后,方可父.

  • printf在信号处理程序内部调用通常是不安全的.但是,如果程序sigsuspend在信号到达时正在睡觉,那么就可以了.用于sigprocmask确保SIGUSR1仅在sigsuspend呼叫期间可交付.(您可以在Linux signal-safety(7)联机帮助页中找到可安全调用信号处理程序的函数列表.)

  • 父节点应该只保存返回给它的子PID,而不是使用共享内存段做聪明的事情fork.

  • 你应该使用sigaction,而不是signal.

  • 您没有检查是否有任何错误.

  • 您没有检查子进程是否已成功退出.