【发布时间】:2013-12-29 21:52:34
【问题描述】:
我写了一个程序,父进程打印出从参数列表接收到的 5 个(彩票)号码。然后子进程生成5个随机数,如果其中一个数等于参数,则向父进程发送SIGUSR1,否则发送SIGUSR2信号。 如果我不使用信号,只需打印孩子的答案,代码就可以正常工作。但是有了这些信号,父进程运行了两次,或者至少它的内容被打印了两次。你能向我解释一下这种行为吗?提前致谢!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
void handler(int signumber){
printf("The child got a hit, my pid: %i\n", getpid());
}
void handler2(int signumber){
printf("The child had no hit!\n");
}
int main(int argc, char* argv[])
{
signal(SIGUSR1,handler);
signal(SIGUSR2,handler2);
int status, child;
int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
int num3 = atoi(argv[3]);
int num4 = atoi(argv[4]);
int num5 = atoi(argv[5]);
if ( num1<0 || num1>45 || num2<0 || num2>45 || num3<0 || num3>45 || num4<0 || num4>45 || num5<0 || num5>45 ){
perror("We need 5 numbers in range of 0 and 45");
exit(1);
}
child = fork();
if(child>0){ //parent
printf("The numbers: %i, %i, %i, %i, %i. my pid: %i \n", num1,num2,num3,num4,num5,getpid());
} else{
int rnd,i,isAnyHit;
isAnyHit = 0;
srand(time(NULL) * (getpid()));
for ( i=0;i<5;i++ ){
rnd = ((rand()%45)+1);
if ( rnd == num1 || rnd == num2 || rnd == num3 || rnd == num4 || rnd == num5 ){
kill(getppid(),SIGUSR1);
isAnyHit++;
}
}
if ( isAnyHit == 0 )
kill(getppid(),SIGUSR2);
}
return 0;
}
【问题讨论】:
-
如果匹配多个号码会怎样?如果所有 5 个数字都匹配正确,您可能会发送 SIGUSR1 5 次?
-
如果您告诉我们哪条消息被重复,将会有所帮助。此外,如果您将消息翻译成英文(那是什么语言?匈牙利语?),我们会更容易阅读代码。奇怪的一件事是你没有让你的父母等待孩子,所以当你到达孩子的 kill(getppid(), ...) 时,你的父母很可能已经退出,你的进程已经被继承通过 init 进程,您正在向 init 发送信号(希望您不是以 root 身份执行此操作!)
-
可能是父级的 printf 被信号中断,两个并发的 printf 混淆了一些数据结构。如果您将
printf("Szülő: A lottó számok: %i, %i, %i, %i, %i. A pid számom: %i \n", num1,num2,num3,num4,num5,getpid());替换为pause();,会起作用吗?通常,C 信号处理程序只需要更改 volatile 变量即可。
标签: c operating-system signals fork