【发布时间】:2019-09-23 10:16:58
【问题描述】:
我编写了以下代码:在 fork() 函数之后,父级向子级发送信号。我认为孩子收到信号并终止。 我不想要这个解决方案,因为我可以通过以下两种方式解决它。 我想知道这个问题的原因是什么?
我最初尝试的代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <wait.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#define maxchild 1
int inchild=-1;
void sighandler(int signo){
char buffer[256];
int a,b=0;
switch(signo){
case SIGUSR1:
printf("SIGUSR1\n");
break;
case SIGUSR2:
printf("SIGUSR2\n");
break;
}
}
int main(){
pid_t ids[maxchild];
struct sigaction control;
control.sa_flags=0;
control.sa_handler=sighandler;
sigemptyset(&control.sa_mask);
sigaction(SIGUSR1,&control,NULL);
sigaction(SIGUSR2,&control,NULL);
for(int i=0;i<maxchild;i++){
ids[i]=fork();
printf("here %d\n",ids[i]);
if(ids[i]==0){
printf("in child\n");
inchild=i+1;
break;
}
}
while(inchild>=0) {
}
// sleep(1);
if(inchild==-1){
for(int i=0;i<maxchild;i++){
printf("child: %d\n parent: %d\n",ids[i],getpid());
kill(ids[i],SIGUSR1);
}
}
if (inchild==-1) wait(NULL);
return 0;
}
当我多次运行代码时,我希望每次都能在输出中看到“SIGUSR1”,但大多数输出是:
here 17573 (or any other positive number)
child: 17573
parent: 17572
然后程序突然终止。 我知道我可以通过两种解决方案来解决它: 1. fork() 函数后父母最常睡觉:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <wait.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#define maxchild 1
int inchild=-1;
void sighandler(int signo){
char buffer[256];
int a,b=0;
switch(signo){
case SIGUSR1:
printf("SIGUSR1\n");
break;
case SIGUSR2:
printf("SIGUSR2\n");
break;
}
}
int main(){
pid_t ids[maxchild];
struct sigaction control;
control.sa_flags=0;
control.sa_handler=sighandler;
sigemptyset(&control.sa_mask);
sigaction(SIGUSR1,&control,NULL);
sigaction(SIGUSR2,&control,NULL);
for(int i=0;i<maxchild;i++){
ids[i]=fork();
printf("here %d\n",ids[i]);
if(ids[i]==0){
printf("in child\n");
inchild=i+1;
break;
}
}
while(inchild>=0) {
}
sleep(1);
if(inchild==-1){
for(int i=0;i<maxchild;i++){
printf("child: %d\n parent: %d\n",ids[i],getpid());
kill(ids[i],SIGUSR1);
}
}
if (inchild==-1) wait(NULL);
return 0;
}
它会正常工作
-
我也可以评论“kill(...)”行来解决问题:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/time.h> #include <wait.h> #include <time.h> #include <unistd.h> #include <signal.h> #define maxchild 1 int inchild=-1; void sighandler(int signo){ char buffer[256]; int a,b=0; switch(signo){ case SIGUSR1: printf("SIGUSR1\n"); break; case SIGUSR2: printf("SIGUSR2\n"); break; } } int main(){ pid_t ids[maxchild]; struct sigaction control; control.sa_flags=0; control.sa_handler=sighandler; sigemptyset(&control.sa_mask); sigaction(SIGUSR1,&control,NULL); sigaction(SIGUSR2,&control,NULL); for(int i=0;i<maxchild;i++){ ids[i]=fork(); printf("here %d\n",ids[i]); if(ids[i]==0){ printf("in child\n"); inchild=i+1; break; } } while(inchild>=0) { } // sleep(1); if(inchild==-1){ for(int i=0;i<maxchild;i++){ printf("child: %d\n parent: %d\n",ids[i],getpid()); // kill(ids[i],SIGUSR1); } } if (inchild==-1) wait(NULL); return 0; }现在我想知道问题的原因。
我想运行第一个代码并查看: 这里(正数) 这里 0 在孩子 孩子:(一个正数) 父母:(正数) SIGUSR1 并且程序必须继续运行,直到我按下 Ctrl+c (当然输出中的行顺序无关紧要)
我不想更改代码,我想知道问题的原因。 提前谢谢你
【问题讨论】:
-
对于初学者,请初始化您正确使用的变量:将所有
struct sigaction control;更改为struct sigaction control = {0}; -
此外,如果您希望父母只要至少有一个孩子还活着,就让它呼叫
wait()的次数与分叉孩子的次数一样多。 -
在信号处理程序中调用非异步安全函数的未定义行为。
-
@EOF 我没有在信号处理程序中调用任何函数!另一方面,如果我只添加一个睡眠就可以了。所以处理程序不是问题的原因。
-
@milad 您正在使用
printf(),它不在安全列表中:man7.org/linux/man-pages/man7/signal-safety.7.html