本文介绍了让孩子处理直到收到父母的信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从父母那里创建N个孩子.我希望所有孩子都同时开始(一项功能-测量时间).因此,我将函数放在信号处理程序中,当父级完成创建(分叉)所有子级时,它将信号(使用kill(children_id))发送给所有子级以使其开始.下面的代码,但它不能按预期方式工作.具体来说,它分叉了所有子节点,但根本不执行功能"measure_time".该功能无关紧要,而是记录执行时间并打印出来.有人可以让我知道我做错了什么吗?

I want to create N children from a parent. I want all the children to start (a function - to measure time) at the same time. So I put the function in a signal handler and when the parent finish creating (fork) all children, it sends the signal (using kill(children_id)) to all children to let make start. The code is below but it doesn't work as expected. Specifically, it forked all children but does not execute function "measure_time" at all. This function does not thing but record execution time and print out.Could someone let me know if I am doing something wrong?

    int n_task = 4;
    for (i = 0; i < n_task; i++){
            pid = fork();
            if (pid < 0){
                    printf("cannot fork!\n");
            } else
            if (pid == 0){ //child
                    printf("printed from child [%d]\n", getpid());
                    signal(SIGUSR1, measure_time); //measure_time is a function
                    exit(0);
            } else {
                    pid_array[i] = pid;
            }
    }

    //This code is executed from parent only
    for (int i = 0; i < n_task; i++)
    {
            kill(pid_array[i], SIGUSR1);
    }

推荐答案

if (pid == 0){ //child
    printf("printed from child [%d]\n", getpid());
    signal(SIGUSR1, measure_time); //measure_time is a function
    exit(0);
}

创建孩子,设置处理程序,然后立即退出(即死亡).让他们睡觉或阻塞某物,这样父母实际上就有时间传递信号了.

The children get created, set up the handler, and immediately exit (i.e. die). Make them sleep or block on something so there is actually time for the parent to deliver the signals.

更新

#define _POSIX_SOURCE

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

void measure_time(int sig)
{
    printf("child [%d] received signal %d\n", getpid(), sig);
}

int main(int argc, char *argv[])
{
    int n_task = 4;

    pid_t pid;
    pid_t pid_array[n_task];

    for (int i = 0; i < n_task; i++)
    {
        pid = fork();

        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }

        if (pid == 0) //child
        {
            printf("printed from child [%d]\n", getpid());
            signal(SIGUSR1, measure_time); //measure_time is a function
            sleep(5);

            exit(0);
        }

        //parent
         pid_array[i] = pid;
    }

    //This code is executed from parent only
    sleep(1);

    for (int i = 0; i < n_task; i++)
        kill(pid_array[i], SIGUSR1);

    for (int i = 0; i < n_task; i++)
        wait(NULL);

    return (0);
}

所有进程和线程均受操作系统调度程序的要求.在您的初始代码中,子级可能会在您希望发生的事件序列发生之前终止.孩子可以在父母发出信号之前就死掉;父级可以在子级设置其处理程序之前发送信号(并且SIGUSR1终止进程,因为这是缺少处理程序时的默认设置).很少有代码可以执行所有这些操作,而只需几毫秒即可完成,这比这些进程中的任何一个计划运行的时间要短(因此设置得足以满足您的期望).我添加了一些sleep为它们提供了所有喘息的空间,并添加了wait,以使父级不会死.这应该可以让您了解它的工作原理.

All processes and threads are subject to whims of the OS scheduler. In your initial code the children and the parent can potentially terminate before the sequence of events you hope to take place can ever occurs. The children can die before the parent ever sends a signal; the parent can send its signals before the children ever set up their handler (and SIGUSR1 kill the process because that is its default in the absence of a handler). There is so little code to execute all this takes place in milliseconds, less than the time than any of these processes gets scheduled to run (and thus setting up enough to fulfill your expections). I have added some sleep to give it all some breathing room and a wait so the parent doesn't die. This should allow you to see how it works.

这篇关于让孩子处理直到收到父母的信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 00:33