2017-03-01 3 views
0

こんにちは私はちょうど2つのプロセス間のシグナリングに取り組んでいます。私はメインプロセス(例えば、MAIN)を実行し続けます。このMAINは、ラッパープロセス(例えば、WRAP)からフォークされます。プロセス間のシグナリングでの問い合わせLinux

実際にWRAPプロセスを起動するコードは、MAINという子プロセスを作成します。

MAINで特定の初期化が完了したら、SIGUSR1という信号を投稿したいと思います。これはWRAPでキャプチャされ、その他のものがあります。

私のコードでの問題は、信号がMAINから発生したときに、それがWRAPプロセスによって決してトラップされないことです。 Pls。このコードであなたの提案を共有したり、これを達成するための他の方法がある場合は、 ありがとうございます。 MAIN過程で

初期化が完了した後、私は、WRAPプロセスで

main() 
{ 
    // Do some work here 
    int pid = GetProcessID(); // Returns the process ID of WRAP process 
    kill(pid,SIGUSR1);  // Tries to send signal to WRAP process 

    // Other code 
} 

int GetProcessID() 
{ 
    int pid = 0; 
    char results[128]; 
    FILE *fp = popen("pgrep WRAP", "r"); 
    if(fp == NULL) 
    { 
     printf("Error: Failed to get Process ID"); 
    } 
    else 
    { 
     while(fgets(results, 128, fp) != NULL) 
     { 
      pid = atoi(results); 
     } 
     pclose(fp); 
    } 
    return pid; 
} 

をこのコードを追加しました:

main() 
{ 
    int pid; 

    signal(SIGUSR1,InitComplete); 

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

    if (pid == 0) 
    { 
     /* child */ 
     system("mainProc.out"); 
    } 
    else 
    { 
     /* parent */ 
     if(KeepListening() == 1) 
      printf("Init completed successfully\n"); 
    } 

    return 0; 
} 

int KeepListening() 
{ 
    const int MAX_WAIT_TIME = 180; 
    int procStarted = 0; 
    int res = 0; 
    sigset_t origset; 
    sigset_t ss; 

    sigemptyset(&ss); 
    sigaddset(&ss, SIGWINCH); 
    sigaddset(&ss, SIGUSR1); 
    res = sigprocmask(SIG_BLOCK, &ss, &origset); 

    if(res) 
    { 
     printf("\nError: sigprocmask returned an error\n"); 
    } 

    struct timespec theTimeout; 
    theTimeout.tv_nsec = 0; 
    theTimeout.tv_sec = MAX_WAIT_TIME; 

    int sig = 0; 
    siginfo_t theInfo; 
    memset(&theInfo, '\0', sizeof(theInfo)); 

    int timedwaitcount = 0; 

    do 
    { 
     sig = sigtimedwait(&ss, &theInfo, &theTimeout); 
     if(sig < 0) 
     { 
      if(EAGAIN == errno) 
      { 
       timedwaitcount++; 
      } 
      else 
      { 
       PrintMessage("Error:Error occured with sigtimedwait\n"); 
      } 
     } 
     else 
     { 
      timedwaitcount = 0; 
     } 

     if(SIGUSR1 == sig) 
     { 
      return 1; 
     } 
    }while(SIGWINCH == sig || 0 == sig); 

    return procStarted; 
} 

void InitComplete() 

    printf("InitComplete in MAIN. Signal Received.\n"); 
} 
+0

を[ENTER]?誰が誰を殺しますか? **完全な**コードを投稿してください。また、フォーク+システム? –

+0

私はexecvp()を使用してプロセスを起動しましたが、何らかの理由でMAINプロセスが数秒後に実行されません。巨大なコードチャンクはラッパーコードであり、MAINプロセスはより多くのLOCのものです。私は信号を上げる必要がある場所から1行だけ追加しました。 – killer

+1

コードが巨大であれば、[mcve]を減らすことはあなたの責任です。これらのガイドラインは、理由により存在します。 'kill(pid、SIGUSR1);の' pid'とは何ですか?誰も知らない。 –

答えて

0

私はどのようにそれが必要実証短いサンプルを用意し作業。 MAINあなたが呼んでいるもののため

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

static int sigUsr1Rcvd = 0; 

enum { SleepTimeUS = 50000 /* us */ }; 

void onSigUsr1(int sig) 
{ 
    if (sig == SIGUSR1) sigUsr1Rcvd = 1; 
} 

int main(int argc, char **argv) 
{ 
    int pid; char buffer[20]; int status = 0; 
    /* report alive */ 
    printf("%s started...\n", argv[0]); 
    /* install signal handler before fork() */ 
    signal(SIGUSR1, &onSigUsr1); 
    /* fork child */ 
    if (pid = fork()) { /* main process */ 
    if (pid < 0) { 
     perror("ERROR in fork()"); 
     return -1; 
    } 
    } else { /* child process */ 
    if (execl("./test-exec-child", "test-exec-child", NULL)) { 
     perror("ERROR in execl()"); 
     return -1; 
    } 
    return 0; 
    } 
    /* main process */ 
    /* waiting for SIGUSR1 */ 
    while (!sigUsr1Rcvd) usleep(SleepTimeUS); 
    printf("%s: Child inited.\n", argv[0]); 
    /* wait for termination of child */ 
    wait(&status); 
    /* done */ 
    printf("%s exiting...\n", argv[0]); 
    return 0; 
} 

ソースコードファイルtest-exec-child.c:あなたはWRAPPER呼んでいるもののため

ソースファイルtest-exec.c

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 

enum { SleepTimeS = 3 /* s */ }; 

int main(int argc, char **argv) 
{ 
    char buffer[20]; 
    /* report alive */ 
    printf("%s started...\n", argv[0]); 
    /* consume some time */ 
    printf("%s: initializing...\n", argv[0]); 
    sleep(SleepTimeS); 
    printf("%s: done.\n", argv[0]); 
    /* send signal to parent */ 
    kill(getppid(), SIGUSR1); 
    /* spend time until user feed-back */ 
    printf("Press [ENTER] to continue..."); 
    fgets(buffer, sizeof buffer, stdin); 
    /* done */ 
    printf("%s exiting...\n", argv[0]); 
    return 0; 
} 

私がコンパイルされ、cygwinの上でgccでこれをテストした:

$ gcc -o test-exec test-exec.c 

$ gcc -o test-exec-child test-exec-child.c 

$ ./test-exec 
./test-exec started... 
test-exec-child started... 
test-exec-child: initializing... 

...

test-exec-child: done. 
./test-exec: Child inited. 
Press [ENTER] to continue... 

あなたは場所を正確にtbisタラを追加した

test-exec-child exiting... 
./test-exec exiting... 

$ 
関連する問題