gpt4 book ai didi

c - 进程间信令查询 Linux

转载 作者:太空宇宙 更新时间:2023-11-04 12:33:58 24 4
gpt4 key购买 nike

您好,我正在研究两个进程之间的信号。我有一个持续运行的主进程(例如 MAIN)。此 MAIN 是从 Wrapper 进程(例如 WRAP)派生出来的。

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

当某些初始化在 MAIN 中完成时,我想发布一个信号 SIGUSR1,它将被 WRAP 捕获并做一些其他事情。

我的代码的问题是,当信号从 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;
}

在 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");
}

最佳答案

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

源文件 test-exec.c 用于您所说的 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;
}

你称之为 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...

$

关于c - 进程间信令查询 Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42524446/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com