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
'Programing' 카테고리의 다른 글
DOCTYPE 선언 전에 주석이 나타날 수 있습니까? (0) | 2020.12.28 |
---|---|
Java의 웹 페이지에서 이미지를 다운로드하는 방법 (0) | 2020.12.28 |
크롬 렌더링 문제. (0) | 2020.12.28 |
UIWebView 배경색 (0) | 2020.12.28 |
자동 완성 콤보 박스를 만드는 방법은 무엇입니까? (0) | 2020.12.28 |