Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 等待返回的过程_C_Process_Waitpid - Fatal编程技术网

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
返回值,如果它被中断,则再次调用它