2017-03-01 3 views
0

Hallo Ich arbeite nur an die Signalisierung zwischen zwei Prozessen. Ich habe einen Hauptprozess (zB MAIN), der weiter läuft. Diese MAIN wird von einem Wrapper-Prozess gespalten (z. B. WRAP).Abfragen in Signalisierung zwischen Prozessen Linux

Hier ist mein Code, der den Prozess WRAP startet, der wiederum einen untergeordneten Prozess wie MAIN erstellen wird.

Wenn bestimmte Initialisierung in MAIN abgeschlossen ist, möchte ich ein Signal SIGUSR1 posten, das von WRAP erfasst wird und einige andere Zeug macht.

Das Problem mit meinem Code ist, wenn das Signal von MAIN ausgelöst wird es nie durch WRAP Prozess gefangen wird. Pls. teile deine Vorschläge zu diesem Code oder wenn es andere Wege gibt, dies zu erreichen. Danke.

Im Hauptprozess:

Nach Init abgeschlossen Ich habe diesen Code hinzugefügt,

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

In WRAP Prozess:

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

Sie hinzugefügt haben TBIs Kabeljau wo genau? Wer tötet wen? Bitte posten ** vollständigen ** Code. Auch Gabel + System ?? –

+0

Früher habe ich execvp() verwendet, um den Prozess zu starten, aber aus irgendeinem Grund wird der MAIN-Prozess nach einigen Sekunden nicht ausgeführt. Der große Code-Chunk ist ein Wrapper-Code und der MAIN-Prozess ist mehr LOC. Ich habe nur eine Zeile hinzugefügt, von wo ich das Signal erhöhen muss. – killer

+1

Wenn der Code riesig ist, liegt es in Ihrer Verantwortung, ihn für einen [mcve] zu reduzieren. Diese Richtlinien existieren aus einem bestimmten Grund. Was ist 'pid' in' kill (pid, SIGUSR1); '? Niemand weiß. –

Antwort

0

bereitete ich eine kurze Probe, die, wie sollte es zeigt, Arbeit.

Quelldatei test-exec.c für das, was Sie rufen WRAPPER:

#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; 
} 

Quellcodedatei test-exec-child.c für das, was Sie MAIN nennen:

#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; 
} 

ich kompiliert und getestet dies mit gcc auf Cygwin:

$ 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... 

[ENTER]

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

$ 
Verwandte Themen