4

親から N 個の子を作成したい。私はすべての子供たちが同時に(機能 - 時間を測定するために)開始することを望んでいます。そのため、関数をシグナル ハンドラーに配置し、親がすべての子の作成 (フォーク) を完了すると、(kill(children_id) を使用して) すべての子にシグナルを送信して開始します。以下にコードを示しますが、期待どおりに動作しません。具体的には、すべての子をフォークしましたが、関数「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);
}

すべてのプロセスとスレッドは、OS スケジューラの気まぐれに左右されます。最初のコードでは、発生させたい一連のイベントが発生する前に、子親が終了する可能性があります。親がシグナルを送信する前に、子が死亡する可能性があります。親は、子がハンドラーをセットアップする前にシグナルを送信できます (そして、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 に答える