我想创建三个进程,这会打印一些东西,直到按ctrl + c。下面你可以看到我的尝试但是当试图停止程序时没有任何反应。当只有一个孩子分叉时,它运作良好。哪里可能有问题?提前谢谢。
void my_handler(int s){
printf("Caught signal %d, I am dying\n",s);
exit(1);
}
void doChild(int count){
fprintf(stdout,"Child %d with pid: %d\n",count, getpid());
}
int main(int argc, char **argv){
int count = 0;
pid_t pid;
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
fprintf(stdout, "Ahoj svjete!\n");
for(;count < 3;count++){
pid = fork();
switch(pid){
case -1:
perror("Fork :(");
exit(EXIT_FAILURE);
case 0:
while(1){
doChild(count);
}
}
}
exit(EXIT_SUCCESS);
}
答案 0 :(得分:2)
正如REACHUS所说,你得到8个进程,而不是3个。此外,交换机在每个进程中测试 last fork calll的结果,因此4个进程立即退出,而其他4个进程继续在doChild
循环中运行。
现在因为顶级进程(执行第一个fork的初始进程)是退出的进程之一(其fork
调用都返回子进程的pids,从不返回0),shell再次接管,这意味着当你点击 ctrl-C 时,它会转到shell而不是你的分叉孩子。那些孩子永远不会看到SIGINT(除非你用kill
明确地发送给他们),所以永远不要退出。
答案 1 :(得分:1)
在这个循环中:
for(;count < 3;count++){
pid = fork();
}
你将创建总共 8个进程,因为你执行fork()
3次,即1.调用fork()
给你1 * 2 = 2个进程,第二次调用fork()
会给你2 * 2 = 4个进程,第三次调用fork()
会给你4 * 2 = 8个进程。
此外,您设置信号处理程序的方式是将信号发送给整个process group(例如父母和孩子)。如果这不是您想要的,您应该查看setpgid()
和setsid()
函数,以使信号分别为每个子进程工作。
修改强>
以下是您的代码的修改版本以及我的一些补充,可帮助您了解正在发生的事情。您还可以在Chris Dodds的答案中找到更多关于代码中发生的事情的解释。发送信号现在将杀死所有子进程和父进程,但是这段代码只是一个例子,你可以了解它是如何工作的(正如我所说,你应该在这里使用进程组)。
void my_handler(int s){
printf("Caught signal %d, I am dying, my PID=%d\n",s, (int)getpid());
exit(1);
}
void doChild(int count){
fprintf(stdout,"Child %d with pid: %d\n",count, getpid());
}
int main(int argc, char **argv){
int count = 0;
int status;
pid_t pid;
for(;count < 2;count++){
pid = fork();
}
printf("My PID=%d\n", (int)getpid());
fprintf(stdout, "Ahoj svjete!\n");
switch(pid){
case -1:
perror("Fork :(");
exit(EXIT_FAILURE);
case 0:
signal(SIGINT, my_handler);
while(1){
doChild(count);
}
default:
printf("Parent\n");
sigignore(SIGINT);
wait(&status);
}
printf("Process %d ended life.\n", (int)getpid());
exit(EXIT_SUCCESS);
}