【问题标题】:Parent process doesn't complete after child is terminated in C子进程在 C 中终止后父进程未完成
【发布时间】:2011-04-14 04:27:43
【问题描述】:

我在进行进程分叉练习时遇到问题。我想分叉一个子进程,并在宣布它被分叉后挂起,并等待信号终止,之后父进程必须宣布它正在终止然后退出。

我可以让进程分叉并让父进程等待挂起的子进程被信号杀死,但它似乎也杀死了父进程。我尝试通过其 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);
    }

}

【问题讨论】:

  • 您显示的代码无法编译 - 您尚未定义 tempPID。你不需要两次&lt;unistd.h&gt;,现在你不需要&lt;sys/types.h&gt;(尽管在一些早期版本的POSIX中,它是必需的)。
  • 这不会编译,即使编译也没有多大意义。 tempPID 完全未声明,并在仅在父进程中使用的信号处理程序中读取,尽管它仅在子进程中设置。至少解决这个问题,我们会看看我们可以从哪里找到你。

标签: c process fork parent


【解决方案1】:

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

再次感谢。

【讨论】:

    【解决方案2】:

    即使假设您修复了代码以使其编译(您尚未定义 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 中的亲戚的标头是 &lt;sys/wait.h&gt;

    而且,因为我是个傻瓜,这里的代码可以编译,甚至可以做你想做的事:

    #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);
    }
    

    【讨论】:

    • 我整理了代码,tempPID 是尝试不同方法杀死孩子的剩余部分。两个进程无限循环的原因是它们正在等待通过按 CTRL+C 发送 SIGINT 信号,我应该澄清一下。还有 Johnathan,如果没有 sys/types.h 来传递 pid_t 的原型,代码将无法编译。
    • @Josh:您在哪个环境中运行仍然需要明确的&lt;sys/types.h&gt;?我已经很久没有遇到过这样的机器了——至少五年了。但是,正如我在最初的评论中指出的那样,曾经有一段时间 POSIX 标准或Single UNIX Specification 1997 标准要求这样做。
    最近更新 更多