2010-09-18 165 views
0

我在进行分叉练习时遇到问题。我想分叉一个子进程,并在声明它已经分叉后让它挂起,等待一个信号终止,之后父进程必须宣布它正在终止然后退出。在C中终止子进程后,父进程未完成

我可以得到进程分叉,并让父母等待悬挂的孩子被信号杀死,但它似乎也杀死了父母。我试图通过PID来杀死儿童进程,但没有成功。

感谢您的帮助!

代码:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <sys/types.h> 


void catchInt (int signum) 
{ 
    printf("\nMy sincerest apologies, master\n"); 
    /*kill(0, SIGINT);*/ 
    exit(0); 
} 

void ignoreInt (int signum) 
{ 
    wait(NULL); 
} 

int main() { 

    pid_t pid; 

    /* fork process */ 
    pid = fork(); 
    if (pid < 0) /* error handler */ 
    {  
     fprintf(stderr, "Fork Failed"); 
     exit(-1); 
    } 

    else if (pid == 0) /* child */  
    { 
     printf("Child reporting in\n"); 
     signal(SIGINT, catchInt); 
     for (;;) 
      pause(); 
    } 

    else /* parent */ 
    { 
     /* parent will wait for the child to complete */ 
     signal(SIGINT, ignoreInt); 
     wait(NULL); 
     printf("You're welcome\n"); 
     exit(0); 
    } 

} 
+1

您显示的代码无法编译 - 您尚未定义tempPID。你不需要''两次,而现在你不需要''(尽管在一些早期版本的POSIX中,它是需要的)。 – 2010-09-18 20:23:00

+1

这不能编译,即使它做了也没什么意义。 'tempPID'完全没有声明,并且只在父进程中使用的信号处理程序中读取,尽管它只在子进程中设置。至少解决这个问题,我们会看到我们可以从那里获得你的位置。 – 2010-09-18 20:24:43

回答

3

即使假设你修复代码,以便它编译(你没有定义tempPID),有问题:

  • 您可以设置孩子去睡觉,直到信号到达。
  • 您设置父级要等到孩子死亡。

所以,你有一个状态,任何进程都不会做更多的事情。

你可能需要家长到的信号发送到孩子:

kill(pid, SIGINT); 
  • 目前尚不清楚,你需要家长设置的信号处理程序。
  • 您可能希望孩子设置信号处理程序。
  • 你可能不想在孩子的无限循环。
  • 噢,和void main()是不正确的 - int main()int main(void)int main(int argc, char **argv)main()的批准声明。
  • 如果你从main()返回一个值(0),它是整洁的。 C99标准确实允许你放弃main()的结尾,并将其视为返回零,但前提是该函数正确声明为返回int
  • wait()的标题和POSIX中的亲属是<sys/wait.h>

而且,因为我是个傻逼,下面是编译,甚至可能做你想要的代码:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h>   /* getpid() */ 
#include <stdlib.h> 
#include <sys/wait.h> 

void catchInt(int signum) 
{ 
    printf("Child's PID is %d\n", (int)getpid()); 
    printf("My sincerest apologies, master\n"); 
    exit(1); 
} 

int main() 
{ 
    pid_t pid = fork(); 
    if (pid < 0) /* error handler */ 
    {  
     fprintf(stderr, "Fork Failed"); 
     exit(-1); 
    } 
    else if (pid == 0) /* child */  
    { 
     printf("Child reporting in\n"); 
     signal(SIGINT, catchInt); 
     pause(); 
    }  
    else /* parent */ 
    { 
     sleep(1); 
     kill(pid, SIGINT); 
     wait(NULL); 
     printf("You're welcome\n"); 
    } 
    return(0); 
} 
+0

我整理了代码,tempPID是尝试用不同方法杀死孩子的剩余废料。两个进程无限循环的原因是他们正在等待SIGINT信号通过按CTRL + C发送,我应该澄清。还有Johnathan,如果没有sys/types.h来传递pid_t的原型,代码将无法编译。 – JKomusin 2010-09-18 20:52:42

+0

@Josh:你在哪个环境中运行,仍然需要明确的''?我很久没有遇到过这样的机器 - 至少五年。但是,正如我在最初的评论中指出的那样,有一次POSIX标准或[Single UNIX Specification 1997](http://www.opengroup.org/onlinepubs/007908799/xsh/getpid.html)标准要求。 – 2010-09-19 00:49:11

0

只是想出了什么,我做错了,我应该意识到SIGINT被发送到每个进程,所以父进程只是被发送一个未处理的SIGINT,导致它退出。感谢所有的帮助(我对草率编码的歉意,我真的不应该等到程序完成清理之后),代码已经在上面进行了编辑并按预期工作。

再次感谢。