this_thread 함수 특징에 대해 정리하고자 한다.
std::thread::id 특징
1. std::this_thread::id를 화면에 출력하면 정수로 표현되지만 실제는 정수 타입이 아니며 변환도 안된다.
//특징 1
int n = tid1; // error.
std::thread::id tid1 = std::this_thread::get_id();
2. 컨테이너에 보관 가능하고, hash도 가능하다
//2. 컨테이너에 보관 가능하고, hash 도 가능
std::vector< std::thread::id> v; // ok..
std::hash< std::thread::id> h; // ok
// 특징 3. == , != 연산 가능합니다.
tid1 == tid1;
3. 연산이 가능하다. (== , != 등)
std::thread::id tid1 = std::this_thread::get_id();
tid1 == tid1;
sleep_for, sleep_until : thread를 재우는 함수
sleep_for : 특정 시간 동안
sleep_until : 특정 시간까지
thread를 재우는 함수의 시간의 입력은 chrono 라이브러리를 이용해서 입력할 수 있다.
chrono 시간/날짜 관련 C++ 표준 라이브러리
#include <iostream>
#include <thread>
#include <chrono>
time_t toUTC(std::tm& timeinfo)
{
#ifdef _WIN32
std::time_t tt = _mkgmtime(&timeinfo);
#else
time_t tt = timegm(&timeinfo);
#endif
return tt;
}
std::chrono::system_clock::time_point createDateTime(int year, int month, int day, int hour, int minute, int second)
{
tm timeinfo1 = tm();
timeinfo1.tm_year = year - 1900;
timeinfo1.tm_mon = month - 1;
timeinfo1.tm_mday = day;
timeinfo1.tm_hour = hour;
timeinfo1.tm_min = minute;
timeinfo1.tm_sec = second;
tm timeinfo = timeinfo1;
time_t tt = toUTC(timeinfo);
return std::chrono::system_clock::from_time_t(tt);
}
int main()
{
// 스레드 재우는 함수 : sleep_for
std::this_thread::sleep_for(3); // error
// => 인자는 chrono 라이브러리 형태로 전달해야 한다.
std::chrono::seconds sec(3);
std::this_thread::sleep_for(sec); // ok
auto t1 = createDateTime(2023, 5, 25, 12, 0, 0);
std::this_thread::sleep_until(t1); // std::chrono::system_clock::time_point type
}
TIP. literals을 이용해서 아래와 같이 시간을 입력할 수도 있다.
#include <chrono>
using namespace std::literals;
std::this_thread::sleep_for(3us);
std::this_thread::sleep_for(3s); // 이렇게도 사용가능
// "user define literal 문법"
// 3s 가 결국 std::chrono::seconds 반환
yield : 자신의 실행 시간을 포기하는 함수
스레드가 자신에게 부여된 실행 시간을 포기(다른 스레드를 실행하라고 하는 것.)
#include <iostream>
#include <chrono>
#include <thread>
// yield 를 사용한 sleep 구현
void little_sleep(std::chrono::microseconds us)
{
auto target = std::chrono::high_resolution_clock::now() + us;
// target : 깨어나야 하는 시간
while (std::chrono::high_resolution_clock::now() < target)
std::this_thread::yield();
}
int main()
{
auto start = std::chrono::high_resolution_clock::now();
little_sleep(std::chrono::microseconds(100));
auto elapsed = std::chrono::high_resolution_clock::now() - start;
std::cout << "waited for "
<< std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()
<< " microseconds\n";
}
결과:
waited for 102 microseconds
위 예제로 보면 사실 거의 지연시간이 없다.
현재 main thread에서 yield를 했기에 영향이 없지만 다른 thread와 동시에 동작 할 때는 자원을 효율적으로 사용할 수 있는 방법이다.
참고
* 본 글에 예제 코드는 코드누리 교육을 받으면서 제공된 샘플코드를 활용하였습니다.
728x90
'L C++ > Concurrency' 카테고리의 다른 글
[Concurrency] 주요 기능 member type / class / functions 정리 (0) | 2023.08.01 |
---|---|
[Concurrency] 인자와 callable object (0) | 2023.07.24 |
[Concurrency] 좀비 스레드 생성될 수 있는가? (0) | 2023.07.18 |
[Utilities] thread를 잘 사용하기 위한 std::reference_wrapper (std::ref) (활용 예시 추가) (0) | 2023.05.28 |
[Utilities] std::reference_wrapper (std::ref) : thread를 잘 사용하기 위해 필요한 템플릿 클래스 (0) | 2023.05.28 |