【问题标题】:The functionality of wait function等待函数的功能
【发布时间】:2022-01-22 08:04:56
【问题描述】:

您好,我正在尝试创建此流程树,但我仍然对是否可以打印 DABC 感到困惑

void main(){
/*
                                     creating this process tree:  
                                                        P1
                                                      /   \
                                                    P2     P3
*/
    if(fork()){
        if(fork()){
            printf("A\n");
            wait(NULL);
            printf("B\n");
        }
        else{
            printf("C\n");
        }

    }
    else{
        printf("D\n");
    }
}

【问题讨论】:

  • wait() 等待任何一个子进程结束。所以是的,有可能以“DABC”结尾。请参阅小提琴(我添加了 sleep() 以帮助获得所需的顺序) - onlinegdb.com/Mycj7Kuuh

标签: c process fork parent-child wait


【解决方案1】:

是的,这是可能的。

事实上,以下所有结果都是可能的:

  • ACBD
  • ACDB
  • 中国农业发展银行
  • ADCB
  • CABD
  • CADB
  • CDAB
  • DABC
  • DACB
  • DCAB

这可以通过拉伸/收缩浅灰色框的组合来可视化。

有一个条件:其中一个子进程必须在 P1 中 wait 之后的语句之前结束。这是因为wait 等待一个孩子——任何孩子——结束。

请注意,您可以使用waitpid 等待特定进程结束。

【讨论】:

  • Re“其中一个子进程必须在 P1 中 wait 之后的语句之前结束。”:如果子进程被信号中断,wait 将在子进程结束之前返回。跨度>
  • @Eric Postpischil,确实,wait 可以被信号中断,但由于没有安装信号处理程序,因此在相关程序中不会发生这种情况。我通常假设设置信号处理程序的人知道这会导致任何阻塞系统调用失败。 // 此答案未涵盖的其他错误:printf 失败和进程被终止。 // 没有考虑缓冲的可能性,但不影响答案。
  • 某些信号的默认值,例如SIGCONT 是丢弃信号。那些会打断wait吗?
【解决方案2】:

我认为练习的目的是您应该假设所有函数调用都成功完成,所有涉及的进程正常终止,并且可以依赖 wait() 调用的返回来指示一个终止子进程,而不是通过信号暂时停止。根据这些假设并考虑所有允许的执行顺序,您应该认识到输出的顺序受这些约束,并且仅这些约束:

  • “A”和“B”将按相对顺序打印,因为这是单个进程的程序顺序。
  • “C”和“D”中的至少一个将在“B”之前打印,因为wait() 确保子进程之一(每个子进程都打印其中一个字母)在打印“B”之前完成.

“DABC”是与这些约束一致的众多序列之一,所以是的,原则上,它是所呈现程序的可能输出。这是否是可能输出是一个完全不同的问题,其答案取决于 C 实现的各种特征及其操作环境。

如果您减少上面列举的假设,那么只会增加可能的输出,因此“DABC”的可能顺序不取决于这些假设。

【讨论】:

  • “C”和“D”可能都打印在“B”之后,因为wait如果被信号中断会返回。
  • @EricPostpischil,我最初的回答是我认为练习的意图和精神。此后,我根据您的评论进行了修订,使其在技术上更加全面。
猜你喜欢
  • 2019-04-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多