fork() 在 C++ 中的工作

Working of fork() in C++

我有这个 C++ 程序。

#include <iostream>
#include <unistd.h>
#include  <sys/types.h>


using namespace std;

int main()
{
    cout<<"*\n";
    fork();
    cout<<"A\n";
    fork();
    cout<<"B\n";
    fork();
    cout<<"C\n";
    return 0;
}

输出为:

*
A
B
C
*
A
B
C

我觉得应该是:

*
A
B
C
A
B
C
B
C
C

说明:'*'应该是一个进程打印出来的。现在,在 fork() 2 'A' 之后应该打印 'B' & 'C'.

Link to code

所以...如果您得到不止一个 * 那么就会发生一些奇怪的事情,我怀疑它是特定于实现的... fork 将为每个子进程提供文件描述符的副本,包括 stdout... 因此在您的实现中它也获得 std::cout 流的有效副本...已经有一个缓冲区加载 *...

我认为如果您将程序更改为包含同花顺,您会看到与我相同的结果:

#include <iostream>
#include <unistd.h>
#include  <sys/types.h>


using namespace std;

int main()
{
    cout<< "*\n";
    flush(cout);
    fork();
    cout<<"A\n";
    flush(cout);
    fork();
    cout<<"B\n";
    flush(cout);
    fork();
    cout<<"C\n";
    flush(cout);
    return 0;
}

根据对该问题的评论,答案是 ideone.com 在线编译器中的 fork 只是将您限制在您的进程的一个实例中,并缓冲您的输出。

Update:其实也是骗人的:http://ideone.com/oXqqwM说明fork()声称成功了,但是只有第一个产生了你进程的新副本.

我怀疑如果你检查了 fork() 的 return 值,你会得到一些关于你所看到的令人惊讶的行为的线索——除了第一个之外,所有的都会有 returned -1 -- 如果你使用 std::endl 而不是你 可能 避免第一个 *.

预期的结果是每个 fork() 在那一刻重复 运行 过程,因此与之前的字符相比,您希望看到每个字符两次,除了缓冲意味着您在 fork().

时缓冲区中可能仍有先前的字符

所以期待 1 个或更多“*”、2 个或更多 "A"、4 个或更多 "B" 或 8 个或更多 "C",除非 fork() 失败, 数量将被限制。

您对 1 个“*”、2 个 "A"、3 个 "B" 和 4 个 "C" 的期望表明您忽略了 两个 进程从一个 fork() 出来会碰到下一个 fork(),所以你加倍,而不是增加一个。