4

我想从父母创建 N 个孩子。我希望所有的孩子同时开始(一个功能 - 测量时间)。所以我把函数放在一个信号处理程序中,当父级完成创建(fork)所有子级时,它会向所有子级发送信号(使用 kill(children_id))让 make 开始。代码如下,但它没有按预期工作。具体来说,它分叉了所有子节点,但根本不执行函数“measure_time”。这个函数的作用是记录执行时间并打印出来。如果我做错了什么,有人可以告诉我吗?

    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);                
    }
4

2 回答 2

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

孩子们被创建,设置处理程序,并立即退出(即死亡)。让他们睡觉或阻止某些东西,这样父母就有时间传递信号。

更新

#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这样父母就不会死。这应该可以让你看到它是如何工作的。

于 2013-11-10T06:40:30.263 回答
1
if (pid == 0){ //child
    printf("printed from child [%d]\n", getpid());                        
    signal(SIGUSR1, measure_time); //measure_time is a function
    pause();
    exit(0);
}

我认为问题是,子进程在创建后立即终止。所以
使用pause()函数等待信号到达。

如果某些子进程无法按预期响应,请尝试此操作。

for (j = 0; j < n_task; j++)
    {
            kill(pid_array[j], SIGUSR1); 
            sleep(1);
    }
于 2013-11-10T07:53:25.583 回答