【发布时间】:2012-02-19 06:29:25
【问题描述】:
您好,我正在构建一个使用如下所示信号处理程序的程序...
struct sigaction pipeIn;
pipeIn.sa_handler = updateServer;
sigemptyset(&pipeIn.sa_mask);
pipeIn.sa_flags = SA_ONESHOT;
if(sigaction(SIGUSR1, &pipeIn, NULL) == -1){
printf("We have a problem, sigaction is not working.\n");
perror("\n");
exit(1);
}
问题是这个处理程序在不应该的时候被绊倒了。唯一应该发送 SIGUSR1 信号的是我的子进程,它存在于一个无限循环中,它监听传入的连接。子进程是分叉的,如下所示。我重做 pipeIn 处理程序以运行子进程使用的父进程不使用的不同函数。代码如下所示。
while(1){
newSock = accept(listenSock,(struct sockaddr *)&their_addr,&addr_size);
printf("A\n");
if(!fork()){
// We want to redefine the interrupt
pid_t th;
th = getpid();
printf("child pid: %d\n",th);
pipeIn.sa_handler = setFlag;
if(sigaction(SIGUSR1, &pipeIn, NULL) == -1){
printf("We have a problem, sigaction is not working.\n");
perror("\n");
exit(1);
}
close(listenSock);
kill(getppid(),SIGUSR1);
waitForP();
}*/
close(newSock);
exit(0);
}
close(newSock);
//waitForP();
//break;
}
当我运行此代码时,我将从另一台计算机进行调用以连接到您在此处看到的我的服务器程序。它将accept() 来自该计算机的一个请求就好了,但随后子进程最终将开始向父进程发送 SIGUSR1。然而,父进程在子进程甚至可以发送信号之前收到 SIGUSR1 信号。处理程序在它应该之前触发函数......然后子进程最终会终止信号并且处理程序第二次关闭。最后,accept() 函数再次关闭,即使没有产生新的连接并且传入的 ip 地址来自一个奇怪的随机 ipv6 地址。我不知道发生了什么事。任何帮助都会很棒。
【问题讨论】:
-
您是否有可能从接受呼叫中获得 EINTR 和错误?看起来你没有检查返回值
-
是的,我确实实现了这个代码的一个版本,我在其中检查了 newSock 的返回值。无论出于何种原因第二次触发,accept() 返回 -1。所以我用我的 fork() 语句过滤了它。第一次触发accept,似乎得到了正确的socket。