※ ios_base::sync_with_stdio(bool sync);
bool sync == false: C 의 stdio.h와 C++의 iostream의 동기화를 끊는다.
bool sync == true: 함수 호출하기 전 이전의 동기화 상태
[sync : true]
- 모든 stream들은 동기화가 되어있으며 동기화된 stream들이 자신의 buffer대신 C stream buffer를 사용
stream buffer: data를 보내거나 받기 전, 임시로 저장되는 곳으로
바로 사용하지 않고 버퍼에서 보관, 어느정도 모이면 출력하는 방식으로 작업함.
- 동기화된 C++ stream들은 thread-safe, 안정성을 보장한다.
- 따라서 입출력 순서가 정해져있어서 race condition이 발생하지 않는다. (race condition: https://chan4im.tistory.com/36)
[sync : false]
- 동기화를 끊게되면 C++ stream은 자신들의 독립적인 buffer를 갖게된다.
- 따라서 입출력 객체를 섞어 사용하면 출력순서를 보장할 수 없어 오답, race condition 발생 가능성이 있다.
- multi-thread의 경우, Thread-unsafe해져서 예상하지 못한 값이 나올 수도 있다.
※ 입출력 속도비교
[scanf, printf, \n] >>>>>>>> [cin, cout, endl]
§ ios_base::sync_with_stdio() 함수
먼저 C++의 <iostream>은 C의 <stdio.h>와 다르다.
C++의 입출력 작업 시, C의 입출력과 동기화 되도록 설계되어 상당히 느린 입출력과정을 겪는다.
추가적으로 endl도 출력문자 출력+출력buffer를 함께 비워 시간이 많이 걸려 \n사용을 권장한다.
이때 말하는 "동기화"를 뜻하는 코드가 ios_base::sync_with_stdio이고, 이 동기화를 풀어주는 코드이다.
따라서 동기화가 풀어진다면? => 당연히 속도를 올릴 수 있다!
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
큰 힘에는 큰 책임이 따른다고, 이런 ios_base::sync_with_stdio에도 치명적인 단점이 있다.
1. 그건 바로 싱글 쓰레드 (single thread) 환경은 괜찮지만, 멀티 쓰레드 (Multi Thread)환경에서는 출력순서가 어그러진다.
즉, 멀티쓰레드 환경에서의 출력순서가 보장될 수 없다는 것이다! (race condition 발생 가능)
cf-1) 코딩테스트에서는 싱글쓰레드만 사용하기에 사용해도 무방하다.
cf-2) 다만 실무에서는 ios_base::sync_with_stdio를 쓰기보단, 속도를 올리기 위해 C입출력 방식을 권장한다.
2. 버퍼가 분리되었기에 cin과 scanf, gets, getchar 등의 C문법 (당연히 출력코드도 동일)을 같이 사용할 수 없다!
cf-2) 싱글, 멀티쓰레드란? https://chan4im.tistory.com/35
§ cin.tie(NULL) / cout.tie(NULL) 함수
[정의]: istream, ostream 즉, stream을 untie 하여 자동으로 입출력 버퍼를 비우지 않게 함
cin과 cout간의 tie를 끊어주는, 즉 다른 입출력이 온다면 기존의 입출력을 비워주도록 하는 것이다.
이 tie를 끊어줌으로써 시간을 많이 절감할 수 있다. (cin을 cout으로부터 풀어줌.)
기본적으로 cout의 출력은 buffer가 가득차거나 수동적으로 flush되기 전까진 출력되지 않는다.
[flush]: 현재 buffer에 저장되있는 내용을 클라이언트로 전송 후 buffer를 비우는 것을 말함.
- stream을 tie하면 다른 stream에서 입출력 요청이 오기 전에 stream을 먼저 flush 시킨다.
- stream을 untie하면 output이 flush되지 않은 채로 user에게 input을 요구한다.
- untie를 해주었다면, cin으로 입력받기 전, 출력하고 싶다면 수동적으로 cout을 flush 해줘야 한다.
[예시]
왼쪽그림에서 ios_base::sync_with_stdio(0);을 지워도 console창은 하게 뜬다.
왼쪽을 보면 cout으로 "입력"이란 문구가 출력된 후 cin이 나오는 것을 알 수 있고, 이는 익숙한 방식이다.
하지만 우측은 입력 후 출력이 모두 동시에 되는 것을 알 수 있다.
우리가 tie를 끊어서 입력 전에 출력관련 문구가 아무리 입력보다 먼저 적혀있었더라도 출력이 되지 않는다.
만약 입력전에 출력되게 하고 싶다면 cout의 buffer를 수동으로 비워줘야 한다.
'Algorithms > Algorithm skill' 카테고리의 다른 글
this.algorithm(5). C 표준 라이브러리 <cmath> ★★☆ (0) | 2022.11.03 |
---|---|
this.algorithm(4). 중복된 원소제거, unique() ★★★ (0) | 2022.11.03 |
this.algorithm(2). merge() 함수, copy() max(), min() 함수 ★★★★★ (0) | 2022.11.02 |
this.algorithm(1). 문자열 처리 (0) | 2022.10.31 |
코딩테스트를 위한 필수 STL 총정리 (★★★★★★★) (0) | 2022.10.29 |