C语言中的fork函数,在返回父进程的PID后杀死父进程。

4

我是C语言新手,过去两周一直在研究forks,我必须为我的操作系统课解决以下问题:

“您必须使用fork创建一个“重量级”进程,然后第一个进程必须等待第二个进程(新进程)返回其父ID,然后它必须杀死其父进程并结束”

我认为这些指令相当令人困惑,这是我到目前为止的代码(正如我所说,我是C语言新手,因此一直在研究)。 我的问题似乎是父进程甚至没有等待子进程返回其ID,因为子进程在那之后就杀死了父进程,因此我认为我正在创建子进程,并且当它运行时,最终会杀死父进程,不让父进程等待子进程执行。(这就是我认为指令混乱的部分) 我想更多地了解fork和进程,以及它们背后的逻辑,这样我编写代码时就可以更加自信。 谢谢!

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


int main() {
    pid_t idProceso;
    int childState;

    idProceso = fork();

    if (idProceso == 0){
        printf ("child id  :  %d. parent id %d\n", 
        getpid(), getppid());

            int parent = getppid();
            kill(parent, SIGKILL);
            printf ("dead parent"); //  not sure about it  ??
            _exit();
    }

    if(idProceso > 0){
        sleep (1);
        printf ("parent id :  %d. child id %d\n", 
        getpid(), idProceso);

        wait (&childState);

    }

    return 0;
}

2
说实话,即使我读了两遍,那句话对我来说也毫无意义。在我能想到的所有情况下,进程都已经被杀死并退出了。 - drahnr
我不明白你应该做什么,但父进程没有等待的原因是它开始了sleep,但子进程被设置为立即终止它,所以就这样做了。 - teppic
你们两个都是对的,我的意思是,我认为这个句子很混乱,但这就是老师给我们的方式。就像: -创建一个进程 -创建一个子进程 -父进程等待子进程 -子进程杀死父进程(这部分让我困惑了),然后它就结束了。 - José Del Valle
3个回答

1
根据您提供的任务描述,我认为分配任务的教师或教授对英语语言或Unix机器上的进程概念都没有很好的掌握。
您提出的解决方案是合理的,但我会删除对sleep的调用。Childstate从未被正确设置,并且您不需要它。此外,不要向父进程发送SIGKILL。SIGKILL是尝试终止进程的最后一种方式。建议向父进程发送SIGTERM。如果您使用Linux机器,则父进程可以使用sigaction安装信号处理程序。在信号处理程序中,您可以打印一个漂亮的消息,例如“从子进程接收到终止信号”,然后调用exit。如果您这样做,您的教授可能会对您的技能印象深刻,从而给您及格分数。
如果失败,我会要求更好的问题。在解决问题之前,向教授提交语法和标点符号修正以获得批准并不罕见。

1

我的问题似乎是父进程甚至没有等待子进程返回它的id

你的程序中没有地方让子进程将其id返回给父进程。唯一发生的通信是子进程向父进程发送SIGKILL信号。

所以我认为我创建了子进程,当它运行时会在结束时杀死父进程,不让父进程等待子进程执行。

是的,你说得对,子进程将使用kill()函数发送SIGKILL信号杀死父进程,但事实上父进程会等待被子进程杀死。

wait (&childState);

父进程在此等待(挂起)子进程终止,子进程终止后,父进程将继续进行,但在您的程序中,当父进程等待子进程终止时,子进程本身将在等待期间终止父进程。

我想更多地了解关于分叉和进程的知识,例如它们背后的逻辑,以便在编写代码时感到更加确定。

这是值得一看的东西


1
$ ./foo.bin
parent id :  6629. child id 6630
child id  :  6630. parent id 6629
dead parentKilled

我刚刚移除了 sleep(1),现在输出结果看起来比较合理。


是的,那就是我目前得到的结果。我唯一想确定的是父进程是否真正在等待(我在wait()之前和之后都放了一个printf,但是它们都没有被打印出来)。 - José Del Valle
1
“parent id : ..... child id ...” 来自于“父进程”,没有合理的理由让“父进程”停留在那里。因此,它会停在等待状态。但是如果你真的想要深入下一层,请使用调试器或调用跟踪器。 - drahnr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接