C++ std::chrono 라이브러리
C++의 chrono 라이브러리는 시간과 관련된 작업을 처리하기 위한 도구다. 이 글에서는 C++ chrono 라이브러리의 세 가지 주요 클럭 구조체와 클럭 구조체와 함께 사용되는 duration, time_point 클래스에 대해 정리해보고자 한다.
🔍 클럭 구조체
클럭 구조체는 다음의 3가지가 존재한다.
- std::chrono::system_clock
- 현재 시스템 시간을 나타내는 클럭이다.
- 시스템 시간이 변경되거나 NTP(Network Time Protocol) 동기화 등으로 수정되면 system_clock의 값도 영향을 받는다.
- Windows에서는 GetSystemTimePreciseAsFileTime 함수를 래핑한 구조체로 구현된다.
- 해상도는 밀리초 수준이다.
- 주로 현재 시간을 출력하고 타임스탬프를 기록하는 데 사용한다.
- std::chrono::steady_clock
- 시간이 항상 앞으로만 흐르는 단조 시계(monotonic clock)이다.
- Windows에서는 QueryPerformanceCounter를 래핑한 구조체로 구현된다.
- 해상도는 나노초 수준이다.
- 시스템 시간이 변경되더라도 영향을 받지 않으므로 정확한 경과시간을 측정할 때 유용하게 사용한다.
- std::chrono::high_resolution_clock
- 시스템에서 가장 높은 해상도를 제공하는 클럭으로, steady_clock이나 system_clock의 alias로 사용된다.
- Windows에서는 steady_clock과 동일한 기능을 제공한다.
즉, 구조체는 3개지만 high_resolution_clock은 그 중 하나의 alias 이므로 사실상 2개나 마찬가지이다.
클럭 구조체의 현재 시간은 now()함수를 통해 가져올 수 있다.
🔍 duration 클래스
duration 클래스는 내부적으로는 시간 단위와 시간 간격을 나타내는 숫자로 구성되며, count()를 통해 객체 내부에 저장된 시간을 정수 값으로 반환할 수 있고 필요에 따라 duration_cast<>()를 통해 원하는 시간 단위로 캐스팅할 수 있다.
- std::chrono::nanoseconds: 나노초
- std::chrono::microseconds: 마이크로초
- std::chrono::milliseconds: 밀리초
- std::chrono::seconds: 초
- std::chrono::minutes: 분
- std::chrono::hours: 시
🔍 time_point 클래스
time_point는 특정 시계의 특정 시점을 나타내는 클래스이다. system_clock()의 경우 time_since_epoch() 함수를 사용하면 epoch(1970년 1월 1일 00:00:00 UTC) 이후 얼마나 경과했는지 반환할 수 있다.
✔️ system_clock을 사용하여 현재 시간을 포맷팅하여 출력하는 예시
➖ C++ 스타일
#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
int main() {
// 현재 시각 time_point로 구하기
auto now = std::chrono::system_clock::now();
// time_t로 변환
time_t now_time = std::chrono::system_clock::to_time_t(now);
// tm 구조체로 변환
struct tm* local = localtime(&now_time);
// C++ 스타일 포맷 출력
std::cout << "현재 시간: "
<< std::put_time(local, "%Y-%m-%d %H:%M:%S")
<< std::endl;
return 0;
}
➖ C 스타일
#include <stdio.h>
#include <time.h>
int main() {
time_t now = time(NULL); // 현재 시간 time_t로 반환
struct tm* local = localtime(&now); // tm 구조체로 변환
// C 스타일 포맷 출력
char buffer[100];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local);
printf("현재 시간: %s\n", buffer);
return 0;
}
현재 시간을 사람이 읽을 수 있는 문자열 형태로 출력하려면 C 스타일과 동일하게 time_t 값으로 변환하고, 다시 tm 구조체로 변환한 다음 시간 포매팅 함수를 사용해 문자열로 출력하는 과정을 거쳐야 한다. 변환 과정을 정리하면 다음과 같다.
- std::chrono::system_clock::now()로 반환한 값은 time_point 객체이다.
- std::chrono::system_clock::to_time_t() 를 사용해 이를 time_t 값으로 변환해야 한다. time_t는 <time.h> 또는 <ctime>에 포함된 타입으로 epoch로부터 경과한 시간을 초단위의 정수로 표현한다.
- <time.h> 또는 <ctime>에 포함된 localtime() 함수를 사용해 time_t를 tm 구조체로 변환한다. tm 구조체는 시각을 년도, 월, 일, 시, 분, 초 단위로 쪼개서 멤버 변수로 저장하며, localtime() 함수는 time_t 포인터를 받아 내부 static 변수로 tm 구조체를 저장해두고 그 주소를 포인터로 반환한다.
- C++ 스타일로는 put_time(), C 스타일로는 strftime() 함수를 사용하면 tm 구조체 포인터를 인자로 받아 사람이 읽기 쉬운 형태의 문자열로 시간을 포매팅할 수 있다.
✔️ steady_clock을 사용하여 코드 실행 시간 측정하는 예시
#include <iostream>
#include <chrono>
int main() {
// 시작 시점 time_point 기록
auto start = std::chrono::steady_clock::now();
// 테스트할 코드
for (int i = 0; i < 1000000; ++i);
// 종료 시점 time_point 기록
auto end = std::chrono::steady_clock::now();
// 경과 시간 계산 (duration 타입)
auto elapsed = end - start;
// duration_cast로 밀리초 단위 변환
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed);
// count()로 숫자 출력
std::cout << "코드 실행 시간: " << ms.count() << "ms" << std::endl;
return 0;
}
🔍 std::this_thread::sleep_for 및 std::this_thread::sleep_until
위 두 함수는 thread 라이브러리에 속하지만 시간지연을 하는 함수로 std::chrono::duration 클래스와 함께 쓰인다.
std::this_thread::sleep_for(std::chrono::seconds(1));
std::this_thread::sleep_until(std::chrono::steady_clock::now() + std::chrono::seconds(3));
'프로그래밍 > C++' 카테고리의 다른 글
C++] Intel hex to bin 변환 프로그램 (TI C2000 시리즈) (0) | 2025.05.24 |
---|---|
C++] explicit 키워드 (0) | 2025.05.06 |
C++ ] uint8_t, int_8t를 스트림 연산자(<<)로 출력할 때의 문제점 (0) | 2025.04.18 |
C++] 파일 입출력시 최적화 방안 (0) | 2025.04.17 |
C++ ] <random> 헤더 사용 난수 생성 (0) | 2024.12.03 |