嗨,我只是在处理两个进程之间的信号。我有一个继续运行的主进程(例如MAIN
)。这个MAIN
是从Wrapper进程分叉的(例如WRAP
)。
以下是我的代码,它实际上会启动WRAP
进程,而后者又会创建一个子进程MAIN
。
当在MAIN中完成某些初始化时,我想发布一个信号SIGUSR1
,该信号将被WRAP
捕获并执行其他一些操作。
我的代码的问题是当信号从MAIN
引发时,它永远不会被WRAP
进程捕获。 PLS。分享您对此代码的建议,或者是否有任何其他方法可以实现此目的。
谢谢。
在MAIN过程中:
在Init完成后,我添加了这段代码,
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 :(得分:0)
我准备了一个简短的样本,演示了它应该如何运作。
您称之为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...
[ENTER]
test-exec-child exiting...
./test-exec exiting...
$