2017-03-01 57 views
0

您好我只是在处理两个进程之间的信号。我有一个持续运行的主进程(如MAIN)。这个MAIN从Wrapper进程派生(例如WRAP)。进程之间的信号查询Linux

这是我的代码,它将实际启动WRAP进程,进而创建子进程为MAIN

当在MAIN中完成某些初始化时,我想发布一个信号SIGUSR1,该信号将被WRAP捕获并执行其他一些操作。

我的代码的问题是当信号从MAIN提出时,它从未被WRAP过程困住。 PLS。在此代码上分享您的建议,或者是否有其他方法可以实现此目标。 谢谢。

在主处理:

初始化完成我已经加入该代码后,

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

在WRAP过程:

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

您已经添加TBIS鳕鱼哪儿?谁杀了谁?请发布**完整**代码。另外,叉+系统? –

+0

早些时候,我使用execvp()来启动进程,但由于某种原因,MAIN进程在几秒后将不会运行。巨大的代码块是一个包装代码,MAIN过程更多的是LOC。我只在需要提升信号的位置添加一行。 – killer

+1

如果代码很大,您有责任将它缩小为[mcve]。这些指导原则是有原因的。 'kill(pid,SIGUSR1)中的'pid';'?没人知道。 –

回答

0

我制备这表明它是如何应该短样品工作。

#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你叫什么MAIN:为你调用包装

源文件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; 
} 

我编译和GCC在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... 

$