2016-10-04 9 views
2

私は、メインプログラムの親から2人の子供を作成します。第1と第2の子は、作成後に(他の子のPIDとともに引数として)プログラム(signalSender)を実行します。 signalSenderはシグナルハンドラを持ち、プロセス間でシグナルを送信するために使用されます。最初の子がsignalShooterを実行するとき、2番目の子のpidは引数としてゼロとして与えられます。 2番目の子がsigShooterを実行すると、最初の子のpidが引数として与えられます。2つの子プロセス間で信号を送信

1)2番目の子が最初の子に信号を送信した後、シグナルハンドラを介して1番目の子のPIDを探したい。グローバル変数pid_t pid2に保存しようとしましたが、動作しません。

2)私はこれらの2人の子供の間でも100回の信号を送信する必要がありますが、どこで 'for loop'と 'wait'信号を使うべきかわかりません。

The main program: 

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

int main() 
{ 
    pid_t pid1,pid2,wid; 
    char *my_args[5]; 
    int aInt = 368 
    char str[15]; 
    pid1 = fork(); 
     if (pid1 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 

     exit(1); 

    } 
    if(pid1 == 0) 
    { 
     my_args[0] = "sigperf1"; 
     my_args[1] = "0"; 
     my_args[2] = NULL; 
     execv("signalSender",my_args); 
     fprintf(stderr,"signalSender cannot be executed..."); 
     exit(-1); 
    } 

    pid2 = fork(); 

    if(pid2 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 
     exit(1); 
    } 

    if(pid2 == 0) 
    { 
     sprintf(str, "%d", pid1); 
     my_args[0] = "sigperf1"; 
     my_args[1] = str; 
     my_args[2] = NULL; 
    // printf("this is converted = %s\n",my_args[1]); 
     execv(“signalSender",my_args); 
     fprintf(stderr,"signalSender cannot be executed..."); 
     exit(-1); 
    } 
wid = wait(NULL); 

} 

signalSender:

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

pid_t pid2; 
struct sigaction act; 

void sighandler(int signum, siginfo_t *info, void *ptr) 
{ 
    printf("Received signal %d\n", signum); 
    printf("Signal originates from process %lu\n", 
     (unsigned long)info->si_pid); 
     pid2 = info->si_pid; 
} 

int main(int argc,char **argv) 
{ 
    memset(&act, 0, sizeof(act)); 
    act.sa_sigaction = sighandler; 
    act.sa_flags = SA_SIGINFO; 
    sigaction(SIGUSR1, &act, NULL); 

    pid_t current, pidOther; 
    current = getpid(); 
    pidOther = atol(argv[1]); 

    if(pidOther != 0) // we are in the second child 
    { 
     kill(pidOther,SIGUSR1); //sending signal from second child to first 
    } 

    if(pidOther == 0) // we are in the first child 
    { 
     kill(pid2,SIGUSR1); 
    } 

    return 0; 
} 
+0

あなたが探している機能は 'pause'または' sigsuspend'だと思います。 – user3386109

答えて

0

あなたはここで同期の問題があります。

両方の子プロセスは、ほぼ同じ時刻に開始します。だから、あなたはどちらが先にkillを予測することはできません。最初の子が最初にkillを実行すると、プロセスグループ内のすべてのプロセスを終了させるpidとして0が渡されます。また、子プロセスはそれぞれ、killを呼び出した直後に終了するため、他の子プロセスが終了する前にシグナルが送信される可能性があります。

いくつかのタイプの同期方法を導入する必要があります。これを行う簡単な方法は、killを呼び出す前に、2番目のプロセスsleepを短時間起動して、最初のプロセスに起動する機会を与えることです。同様に、最初のプロセスはpauseを呼び出す必要があり、信号を受信するまで待機するよう指示します。

これを実行すると、各プロセスはpausekillをループして前後に移動できます。

if(pidOther != 0) // we are in the second child 
{ 
    sleep(1); // wait for first child to start 
    kill(pidOther,SIGUSR1); //sending signal from second child to first 
    for (i=0;i<5;i++) { 
     pause(); 
     kill(pidOther,SIGUSR1); 
    } 
} 

if(pidOther == 0) // we are in the first child 
{ 
    pause(); // wait until we get a signal from the second child 
    kill(pid2,SIGUSR1); 
    for (i=0;i<5;i++) { 
     pause(); 
     kill(pid2,SIGUSR1); 
    } 
} 
+1

良い分析ですが...睡眠は石膏のようです。確かに保証された同期が保証される必要がありますか?私たちが本当にこの問題に本当に答えているかどうかはわかりません。 – Joe

+0

はいそれは動作しません –

関連する問題