ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ios::sync_with_studio, cin.tie, cout.tie
    Programming/_C++ 2023. 5. 14. 18:40

    - 위의 세가지를 사용하기 위해서는 C와 C++의 입출력을 혼용하지 않으면서, thread를 사용할 때 주의를 해야 합니다.


    1. ios::sync_with_studio(bool_sync);

    위의 구문은 C++ 표준 스트림들이 C표준 스트림들과 각각의 입출력 연산 후에 동기화 여부를 설정해줍니다.

     

    false or 0: bool_sync에 다음 값을 넣게 되면, C 표준 stream과 C++ 표준 stream의 동기화를 끊게 됩니다.

     

    bool_sync = false == (0)

     동기화를 끊는다면, C++ stream은 독립적인 버퍼를 갖게 되어서 C와 C++의 입출력 방식을 혼용하여 쓰면 위험합니다.

    Multi-thread를 사용하는 경우 Thread-unsafe가 되어서 예상하지 못한 값이 나올 수 있습니다.

     

    - example

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	ios::sync_with_stdio(0); // false == 0
    
    	cout << "1\n";
    
    	printf("2\n");
    
    	cout << "3\n";
    }

    - result

    결과를 보면 다음과 같이 입출력 순서를 보장 받을 수 없다.

     

     

    bool_sync = true == (1)

     기본적으로 모든 표준 stream들은 동기화 되어 있으며, 동기화된 C++ stream들이 자신의 버퍼 대신 C++ stream의 입출력 연산들이 이에 대응되는 C stream 버퍼를 사용하게 됩니다.

    그렇기에 C와 C++의 입출력 방식을 자유롭게 혼용이 가능하다고 합니다.

     

    또한 위에서는 Thread-unsafe가 되지만, 동기화된 C++ stream들은 Thread-safe를 보장합니다.

    즉, 여러 thread에서 각각 출력 연산을 수행할 수 있고, 경쟁 상태(race condition)이 발생하지 않는다고 합니다.

     

    - example

    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	ios::sync_with_stdio(1); // true == 1
    
    	cout << "1\n";
    
    	printf("2\n");
    
    	cout << "3\n";
    }

    - result

     

    → visual studio 2022에서 실행을 해보면 false, true 둘 다 순서대로 나옵니다.


    2. cin.tie(), cout.tie()

    cin과 cout은 default로 묶여(tie)있습니다.

    tie한다는 것은 두 stream이 sync가 되어 있어서 한 stream에서 다른 stream이 작업을 요청하면,

    작업했던 내용을 flush 합니다.

    → flush는 buffer에 쌓아둔 데이터를 모두 가져오는 것을 말합니다.

     

    만약, 입출력의 변환이 빈번하게 이루어지는 경우 untie를 하게 되면 입출력이 빨라지게 됩니다.

    하지만, 동기화와 똑같이 untie를 하게 되면, 출력이 flush되지 않고 입력을 받는 경우가 발생할수도 있습니다.

     

    - example

    std::cout << "Enter name: ";
    std::cin >> name;

     

    if tie

    프로그램이 입력을 요구하기 전에 output이 flush됩니다.

     

    if untie

    output이 flush되지 않은 채로 입력을 요구하게 됩니다.

    (하지만, vs상에서는 정상적으로 출력이 됩니다.)


    3. 번외 std::endl, stream buffer

    - std::endl

    개행을 할 때 endl 대신 \n을 쓰게 되면 속도가 훨씬 빨라집니다.

    그 이유는 endl이 줄바꿈을 하는 것과 동시에 flush를 하기 때문입니다.

     

    - stream buffer

    stream buffer는 데이터를 보내거나 받아들이기 전에 임시로 저장을 하는 곳 입니다.

    실제 사용자가 1 byte를 읽는다고 한다면, 프로그램은 한꺼번에 (예를 들어 256 byte) 가지고 와서 stream buffer에 저장을 해 놓은 뒤에 사용자가 요청할 때마다 1 byte 씩 꺼내서 사용하게 됩니다.

     

    이는 하드디스크에서 읽어오는 작업이 매우 느리기 때문에 딜레이를 줄이기 위해서 입니다.

     

    'Programming > _C++' 카테고리의 다른 글

    C++_function  (0) 2023.07.21
    C++_for_while_(loop statement)  (0) 2023.07.20
    C++_if (conditional statement, 조건문)  (0) 2023.07.20
    C++_upper_lower  (0) 2023.06.16
    C++?  (0) 2023.06.05
Designed by Tistory.