繁体   English   中英

Linux之间进程之间的信令查询

[英]Queries in signalling between processes Linux

嗨,我只是致力于两个进程之间的信令。 我有一个不断运行的主进程(例如MAIN )。 MAIN是由包装程序(例如WRAP )派生的。

这是我的代码,它将实际启动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");
}

我准备了一个简短的示例,演示了它应该如何工作。

您称为WRAPPER的源文件test-exec.c

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

您称为MAIN的源代码文件test-exec-child.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...

[输入]

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

$

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM