std :: flush는 어떻게 작동합니까?
누군가가 어떻게 std::flush
작동 하는지 설명해 주 시겠습니까?
- 뭔데?
- 언제 하천을 비우시겠습니까?
- 왜 중요 함?
감사합니다.
무슨 std::flush
일이 벌어 질지 에 대한 답변이 없었기 때문에 여기에 실제로 무엇이 있는지에 대한 세부 사항이 있습니다. std::flush
A는 조작 , 즉, 특정의 서명 기능. 간단하게 시작하려면 std::flush
서명 이 있는 것을 생각할 수 있습니다.
std::ostream& std::flush(std::ostream&);
하지만 현실은 조금 더 복잡합니다 (관심이 있다면 아래에서도 설명합니다).
스트림 클래스는이 형식의 연산자를 사용하는 출력 연산자를 오버로드합니다. 즉, 조작자를 인수로 사용하는 멤버 함수가 있습니다. 출력 연산자는 객체 자체를 사용하여 조작자를 호출합니다.
std::ostream& std::ostream::operator<< (std::ostream& (*manip)(std::ostream&)) {
(*manip)(*this);
return *this;
}
당신이 "출력"때 즉, std::flush
로가에 std::ostream
, 그냥 해당 함수를 호출, 즉, 다음 두 명령문은 동일합니다 :
std::cout << std::flush;
std::flush(std::cout);
이제 std::flush()
그 자체는 매우 간단합니다.를 호출하는 것뿐입니다 std::ostream::flush()
. 즉, 다음과 같은 구현을 상상할 수 있습니다.
std::ostream& std::flush(std::ostream& out) {
out.flush();
return out;
}
이 std::ostream::flush()
함수 std::streambuf::pubsync()
는 스트림과 관련된 스트림 버퍼 (있는 경우)를 기술적으로 호출 합니다. 스트림 버퍼는 문자를 버퍼링하고 사용 된 버퍼가 오버플로 될 때 또는 내부 표현이 다음과 동기화되어야 할 때 문자를 외부 대상으로 보내는 역할을합니다. 외부 대상, 즉 데이터가 플러시 될 때. 순차 스트림에서 외부 대상과 동기화한다는 것은 버퍼링 된 문자가 즉시 전송된다는 것을 의미합니다. 즉,을 사용 std::flush
하면 스트림 버퍼가 출력 버퍼를 플러시합니다. 예를 들어, 데이터가 콘솔에 기록 될 때 플러싱으로 인해이 지점에서 콘솔에 문자가 나타납니다.
이것은 질문을 제기 할 수 있습니다. 문자가 즉시 작성되지 않는 이유는 무엇입니까? 간단한 대답은 문자 쓰기가 일반적으로 상당히 느리다는 것입니다. 그러나 합리적인 양의 문자를 쓰는 데 걸리는 시간은 본질적으로 어디에 하나만 쓰는 것과 동일합니다. 문자의 양은 운영 체제, 파일 시스템 등의 여러 특성에 따라 다르지만 종종 최대 4k 문자가 하나의 문자와 거의 같은 시간에 기록됩니다. 따라서 외부 대상의 세부 사항에 따라 버퍼를 사용하여 문자를 보내기 전에 버퍼링하면 성능이 크게 향상 될 수 있습니다.
위의 질문은 세 가지 질문 중 두 가지에 답해야합니다. 나머지 질문은 : 언제 스트림을 플러시 할 것인가? 대답은 다음과 같습니다. 문자를 외부 대상에 써야 할 때! 이 파일을 작성하는 단부에있을 수있다 (참고 사용자 입력을 요청하기 전에 즉시 (암시 파일을 닫는 비록 버퍼를 플러시) std::cout
로부터 판독 될 때 자동적으로 플러싱 std::cin
로 std::cout
인 std::istream::tie()
'내지 D std::cin
). 스트림을 명시 적으로 플러시하려는 경우가 몇 가지있을 수 있지만 매우 드뭅니다.
마지막으로, std::flush
실제로 무엇인지에 대한 전체 그림을 제공하겠다고 약속했습니다 . 스트림은 서로 다른 문자 유형을 처리 할 수있는 클래스 템플릿입니다 (실제로는 char
및 작업을 wchar_t
수행합니다. ). std::flush
스트림의 모든 인스턴스화와 함께 사용할 수 있으려면 다음 과 같은 서명이있는 함수 템플릿이됩니다.
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& std::flush(std::basic_ostream<cT, Traits>&);
사용하는 경우 std::flush
의 인스턴스 즉시 std::basic_ostream
그것은 정말 문제가되지 않습니다 : 컴파일러의 추론 템플릿 인수를 자동으로. 그러나이 함수가 템플릿 인수 추론을 용이하게하는 것과 함께 언급되지 않은 경우 컴파일러는 템플릿 인수를 추론하지 못합니다.
기본적으로 std::cout
는 버퍼링되며 실제 출력은 버퍼가 가득 차거나 다른 플러싱 상황이 발생했을 때만 인쇄됩니다 (예 : 스트림의 개행). 경우에 따라 인쇄가 즉시 이루어 지도록하고 수동으로 플러시해야합니다.
예를 들어, 단일 점을 인쇄하여 진행률 보고서를보고한다고 가정합니다.
for (;;)
{
perform_expensive_operation();
std::cout << '.';
std::flush(std::cout);
}
플러싱이 없으면 오랫동안 출력을 볼 수 없습니다.
참고 std::endl
플러시에 원인뿐만 아니라 스트림에 줄 바꿈을 삽입합니다. 플러싱은 약간 비싸기 때문에 플러싱이 std::endl
명시 적으로 원하지 않는 경우 과도하게 사용해서는 안됩니다.
다음은 플러시가하는 일을 관찰하기 위해 작성할 수있는 짧은 프로그램입니다.
#include <iostream>
#include <unistd.h>
using namespace std;
int main() {
cout << "Line 1..." << flush;
usleep(500000);
cout << "\nLine 2" << endl;
cout << "Line 3" << endl ;
return 0;
}
Run this program: you'll notice that it prints line 1, pauses, then prints line 2 and 3. Now remove the flush call and run the program again- you'll notice that the program pauses and then prints all 3 lines at the same time. The first line is buffered before the program pauses, but because the buffer is never flushed, line 1 is not outputted until the endl call from line 2.
A stream is connected to something. In the case of standard output, it could be the console/screen or it could be redirected to a pipe or a file. There is a lot of code between your program and, for example, the hard disk where the file is stored. For example, the operating system is doing stuff with any file or the disk drive itself might be buffering data to be able to write it in fixed size blocks or just to be more efficient.
When you flush the stream, it tells the language libraries, the os and the hardware that you want to any characters that you have output so far to be forced all the way to storage. Theoretically, after a 'flush', you could kick the cord out of the wall and those characters would still be safely stored.
I should mention that the people writing the os drivers or the people designing the disk drive might are free to use 'flush' as a suggestion and they might not really write the characters out. Even when the output is closed, they might wait a while to save them. (Remember that the os does all sorts of things at once and it might be more efficient to wait a second or two to handle your bytes.)
So a flush is a sort of checkpoint.
One more example: If the output is going to the console display, a flush will make sure the characters actually get all the way out to where the user can see them. This is an important thing to do when you are expecting keyboard input. If you think you have written a question to the console and its still stuck in some internal buffer somewhere, the user doesn't know what to type in answer. So, this is a case where the flush is important.
참고URL : https://stackoverflow.com/questions/14105650/how-does-stdflush-work
'Programing' 카테고리의 다른 글
android 내 자신의 활동을 만들고 확장하는 방법은 무엇입니까? (0) | 2020.11.14 |
---|---|
직접 실행 창에서 동적으로 인해 'Microsoft.CSharp.RuntimeBinder.Binder'가 정의되지 않았거나 가져온 오류가 발생합니다. (0) | 2020.11.14 |
스크립트가로드 된 후 자바 스크립트 함수 호출 (0) | 2020.11.14 |
Intellij 확대 / 축소 방법 (0) | 2020.11.14 |
AngularJS 지시문은 범위 변수 변경시 업데이트되지 않습니다. (0) | 2020.11.14 |