考虑:

int main()
{
        if (fork() == 0){
            printf("a");
        }
        else{
            printf("b");
            waitpid(-1, NULL, 0);
        }
        printf("c");
        exit(0);
 }

(来自计算机系统,布莱恩特-奥哈拉隆)。
我们需要所有可能的输出序列。
我回答:acbc,abcc,bacc。
但是,与解决方案(bcac)相比,我缺少一个输出。我认为这个输出是不可能的,因为父进程在打印c(waitpid)之前等待其子进程返回。这不是真的吗?为什么?在这种情况下,上面的代码和没有waitpid行的代码有什么区别?

最佳答案

我不认为有任何可能。一开始,我以为会有一些诡计,因为stdio缓冲区会以意外的顺序刷新。但即便如此:
子项只有在输出bcac之后才会输出c。因此,a中的第一个c必须来自父代。
父级在完成bcac之前不会输出c。但这种情况只有在孩子完成后才能发生,包括在waitpid期间发生的最后一次stdio刷新。因此,第一个exit()总是来自孩子。
矛盾的证明已经实现了。。。输出不能小于cc>。
好吧,你可以做一件事来扰乱秩序。你可以在一个已经有一个即将退出的孩子的过程中执行这个程序。如果预先存在的孩子在新的孩子打印c之前退出,那么主进程将检测到bcac的退出,并继续打印它的东西,并在孩子打印任何东西之前退出。
这是在setuid程序中要注意的一点:不要假设因为您的程序只创建了一个子进程,所以它只有一个子进程。如果你在高级防御代码学习环境中,这个答案是有意义的。在unix新手环境中,这似乎并不相关,最好说a是不可能的,尽管从技术上讲这不是真的。

10-08 15:01