C 等待返回的过程
考虑:C 等待返回的过程,c,process,waitpid,C,Process,Waitpid,考虑: int main() { if (fork() == 0){ printf("a"); } else{ printf("b"); waitpid(-1, NULL, 0); } printf("c"); exit(0); } (来自计算机系统,布莱恩特-奥哈拉隆) 要求我们提供所有可能的输出序列 我回答:acbc,ab
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行的代码有什么区别呢?我看不出有任何方法可以
bcac
。起初,我以为会有一些骗局,因为stdio缓冲区会以意外的顺序刷新。但即便如此:
在输出a
之前,子级不会输出c
。因此,bcac
中的第一个c
必须来自父级
在waitpid
完成之前,父级不会输出c
。但是,在子进程完成之前,这是不可能发生的,包括在exit()
期间发生的最后一次stdio刷新。因此,第一个c
始终来自子级
矛盾证明已经实现。。。输出不能是bcac
嗯,你可以做一件事来扰乱秩序。您可以在已经有一个子进程即将退出的进程内执行该程序。如果预先存在的子进程在新子进程打印a
之前退出,则主进程将使用waitpid
检测该退出,并继续打印其内容,并且可能在子进程打印任何内容之前退出
这是setuid程序中需要注意的一点:不要因为您的程序只创建了一个子进程而认为它只有一个子进程。如果您处于高级防御代码学习环境中,这个答案是有意义的。在unix新手的上下文中,这似乎不相关,最好说
bcac
是不可能的,尽管从技术上讲这是不正确的。我看不出bcac
有任何可能。起初,我以为会有一些骗局,因为stdio缓冲区会以意外的顺序刷新。但即便如此:
在输出a
之前,子级不会输出c
。因此,bcac
中的第一个c
必须来自父级
在waitpid
完成之前,父级不会输出c
。但是,在子进程完成之前,这是不可能发生的,包括在exit()
期间发生的最后一次stdio刷新。因此,第一个c
始终来自子级
矛盾证明已经实现。。。输出不能是bcac
嗯,你可以做一件事来扰乱秩序。您可以在已经有一个子进程即将退出的进程内执行该程序。如果预先存在的子进程在新子进程打印a
之前退出,则主进程将使用waitpid
检测该退出,并继续打印其内容,并且可能在子进程打印任何内容之前退出
这是setuid程序中需要注意的一点:不要因为您的程序只创建了一个子进程而认为它只有一个子进程。如果您处于高级防御代码学习环境中,这个答案是有意义的。在unix新手上下文中,这似乎不相关,最好只说
bcac
是不可能的,尽管从技术上讲这是不正确的。这很棘手,但是对waitpid
的调用可能会被中断(返回-1
,错误号是EINTR
)。在这种情况下,父级可以在子级输出任何内容之前输出c
,并且可以输出bcac
为了防止发生
bcac
,需要设置信号掩码,或者更好的是,检查waitpid
返回值,如果它被中断,则再次调用它 这很棘手,但是对waitpid
的调用可能会被中断(返回-1
,错误号为EINTR
)。在这种情况下,父级可以在子级输出任何内容之前输出c
,并且可以输出bcac
为了防止发生bcac
,需要设置信号掩码,或者更好的是,检查waitpid
返回值,如果它被中断,则再次调用它