이 글에서는 C++11의 기능을 활용해 타이머를 만드는 방법을 살펴봅니다. 여기서는 later라는 이름의 클래스를 하나 작성할 것입니다. 이 클래스는 다음과 같은 속성을 가집니다.
- int – 코드가 실행되기까지 대기할 시간(밀리초 단위)
- bool – 이 값이 true이면 즉시 반환되고, 지정된 시간이 지난 후 별도의 스레드에서 코드를 실행합니다.
- 가변 인자(variable arguments) – std::bind에 전달하고자 하는 인자들
또한 chrono::milliseconds를 nanoseconds, microseconds 등으로 변경하면 타이머의 정밀도를 자유롭게 조절할 수 있습니다.
예제 코드
#include <functional>
#include <chrono>
#include <future>
#include <cstdio>
class later {
public:
template <class callable, class... arguments>
later(int after, bool async, callable&& f, arguments&&... args){
std::function<typename std::result_of<callable(arguments...)>::type()> task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));
if (async) {
std::thread([after, task]() {
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}).detach();
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(after));
task();
}
}
};
void test1(void) {
return;
}
void test2(int a) {
printf("result of test 2: %d\n", a);
return;
}
int main() {
later later_test1(3000, false, &test1);
later later_test2(1000, false, &test2, 75);
later later_test3(3000, false, &test2, 101);
}실행 결과
$ g++ test.cpp -lpthread $ ./a.out result of test 2: 75 result of test 2: 101 $
위 실행 결과를 보면 첫 번째 결과는 프로그램 시작 후 약 4초 뒤에 출력되며, 두 번째 결과는 첫 번째 결과로부터 약 3초 뒤에 출력됩니다. 이처럼 later 클래스를 사용하면 동기(async = false) 또는 비동기(async = true) 방식으로 원하는 시간만큼 지연시킨 후 함수를 실행하는 타이머를 간단하게 구현할 수 있습니다.