执行父代码的子进程(fork 之前的行)
Child process executing parent code (lines before the fork)
我很难理解 fork()
的行为。我认为子进程将执行 fork()
“之后”的行。所以我预计只会看到一个“Hello world!”,但是这段代码:
printf("Hello World!\n");
fork();
return 0;
输出两个“Hello World”。这是为什么?
我还从使用 pipe()
的在线示例中注意到,管道是在分叉子项之前创建的。父进程创建管道后子进程怎么也有管道呢?
第一个问题很可能与您程序的文件缓冲模式有关,它可能使用全缓冲设置,这意味着只有在缓冲区 (stdout
) 已满时才写入流,这会延迟输出,child过程也会输出,因为它有相同的stdout
.
如果您在 printf
之后立即使用 fflush(stdout)
,或者如果您将缓冲模式 (setvbuf
) 更改为行缓冲或根本不缓冲,您将防止重复输出,因为它将发生在 fork
.
之前
至于第二个问题,正如您正确提到的,child 进程在 fork
之后复制了 parent 进程的代码,但它也复制了文件 table。通过在 fork
之前创建未命名管道,您将确保 child 具有相同的文件描述符。这通常用于设置 child 和 parent 进程之间的管道通信。
您可以检查两个进程中每个进程的 /proc/<process id>/fd
文件夹以确认这一点。
脚注
为了将来参考,这是两个不同的主题,尽管是切线的,但它们属于不同的问题,您可以在此处看到其中一个问题,该问题与第一个问题相关的重复项很接近,但与第二个问题无关碰巧它并没有没有得到答复,它仍然隐藏在不同的问题中并且几乎无法被其他用户发现。
当我们 fork 时,子进程获得父进程地址 space 的精确副本。所以应该预料到这样的行为。管道系统调用returns一个文件描述符,父进程和子进程都有这个描述符。
我很难理解 fork()
的行为。我认为子进程将执行 fork()
“之后”的行。所以我预计只会看到一个“Hello world!”,但是这段代码:
printf("Hello World!\n");
fork();
return 0;
输出两个“Hello World”。这是为什么?
我还从使用 pipe()
的在线示例中注意到,管道是在分叉子项之前创建的。父进程创建管道后子进程怎么也有管道呢?
第一个问题很可能与您程序的文件缓冲模式有关,它可能使用全缓冲设置,这意味着只有在缓冲区 (stdout
) 已满时才写入流,这会延迟输出,child过程也会输出,因为它有相同的stdout
.
如果您在 printf
之后立即使用 fflush(stdout)
,或者如果您将缓冲模式 (setvbuf
) 更改为行缓冲或根本不缓冲,您将防止重复输出,因为它将发生在 fork
.
至于第二个问题,正如您正确提到的,child 进程在 fork
之后复制了 parent 进程的代码,但它也复制了文件 table。通过在 fork
之前创建未命名管道,您将确保 child 具有相同的文件描述符。这通常用于设置 child 和 parent 进程之间的管道通信。
您可以检查两个进程中每个进程的 /proc/<process id>/fd
文件夹以确认这一点。
脚注
为了将来参考,这是两个不同的主题,尽管是切线的,但它们属于不同的问题,您可以在此处看到其中一个问题,该问题与第一个问题相关的重复项很接近,但与第二个问题无关碰巧它并没有没有得到答复,它仍然隐藏在不同的问题中并且几乎无法被其他用户发现。
当我们 fork 时,子进程获得父进程地址 space 的精确副本。所以应该预料到这样的行为。管道系统调用returns一个文件描述符,父进程和子进程都有这个描述符。