[英]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.