Programing

fork () 및 출력

lottogame 2020. 12. 28. 07:44
반응형

fork () 및 출력


간단한 프로그램이 있습니다.

int main()
{
    std::cout << " Hello World";
    fork();
}

프로그램이 내 출력을 실행 한 후 : Hello World Hello World. 단일 대신 왜 이런 일이 발생 Hello world합니까? 나는 자식 프로세스가 뒤에서 다시 실행되고 출력 버퍼가 프로세스 또는 그 라인을 따라 무언가간에 공유된다고 추측하고 있지만 그 경우입니까 아니면 다른 일이 발생합니까?


이것은 원래 생각했던 것과는 다릅니다. 출력 버퍼는 공유되지 않습니다. 포크를 실행하면 두 프로세스 모두 동일한 버퍼의 복사본을 얻습니다 . 따라서 포크 후 두 프로세스는 결국 버퍼를 플러시하고 내용을 별도로 화면에 인쇄합니다.

이것은 cout이 버퍼링 된 IO이기 때문에 발생합니다 . 버퍼링되지 않은 cerr을 사용한 경우 메시지를 한 번만 표시해야합니다.


표준 출력은 버퍼링 된 IO를 사용합니다. (가) 때 fork()표준 출력라고 플러시하고 버퍼링 된 콘텐츠는 자식 프로세스에 복제됩니다. 이러한 버퍼는 프로세스가 종료 될 때 플러시되어 두 개의 출력이 표시됩니다.

프로그램을 다음과 같이 변경하는 경우 :

std::cout << " Hello World;" << std::endl;

하나만 표시되어야합니다.


모든 버퍼를 먼저 비우지 않고 fork ()를 호출했기 때문입니다.

cout.flush();
fork();

출력 할 코드 "Hello World"는 한 번만 실행됩니다. 문제는 출력 버퍼가 플러시되지 않는다는 것입니다. 따라서 프로세스를 포크 "Hello World"해도 여전히 출력 버퍼에 있습니다. 두 프로그램이 모두 종료되면 출력 버퍼가 플러시되고 출력이 두 번 표시됩니다.

이를 입증하는 가장 쉬운 방법은 문자열 끝에 개행 문자를 추가하는 것입니다. 이로 인해 암시 적 플러시가 발생하거나 std::cout.flush();. 그러면 출력이 한 번만 표시됩니다.


사용하는 경우 :

std::cout << " Hello World" << std::flush;

당신은 하나만 볼 수 있습니다. fork()출력 버퍼가 std::cout쓰는 모든 것을 복사 한다고 생각 합니다.


문자열은 화면에 즉시 기록되지 않습니다. 대신 내부 버퍼에 기록됩니다. 자식 프로세스는 출력 버퍼의 복사본을 상속하므로 자식 cout이 자동으로 플러시 될 때 Hello World화면에 인쇄됩니다. 부모는 또한 Hello World.

cout전에 플러시 fork()하면 문제가 거의 사라질 것입니다.


그 이유는 호출 std::cout<<실제로 출력 자체를 수행하지는 않지만 데이터는 시스템의 버퍼에 남아 있기 때문입니다. 포크를 수행하면 코드와 데이터가 모두 복사되고 관련된 모든 버퍼가 복사됩니다. 마지막으로, 아버지와 아들 모두 표준 출력으로 플러시하므로 출력이 중복 된 것을 볼 수 있습니다.


여기에서 볼 수있는 것은 버퍼링의 효과입니다. 일반적으로 출력은 명시 적으로 플러시되거나 새 줄을 출력하는 것과 같은 작업으로 암시 적으로 수행 될 때까지 버퍼링됩니다. 출력이 버퍼링되기 때문에 분기 된 프로세스의 두 사본 모두 버퍼링 된 출력을 가지므로 둘 다 버퍼를 종료하고 플러시하는 프로세스에이를 표시합니다.

참조 URL : https://stackoverflow.com/questions/9364410/fork-and-output

반응형