待ち処理 続き
前回の記事を書いた後に、
「ミリ秒未満の端数分だけ、while ループで待ち処理すればいいんじゃね?」
と、思い改良しました。
使い勝手は前回と変わらず。
#include <boost/chrono.hpp> #include <boost/chrono/timer.hpp> #include <boost/utility/enable_if.hpp> #include <Windows.h> #include "sleep.hpp" #include <iostream> int main(){ using kmt_ex::sleep; namespace chrono = boost::chrono; sleep( chrono::milliseconds(30) ); // WINAPI Sleep(); sleep( chrono::nanoseconds(50) ); // while loop sleep( chrono::seconds(1) ); // WINAPI Sleep(); sleep( chrono::microseconds(40) ); // while loop sleep( chrono::nanoseconds(chrono::seconds(1)) ); // while loop // Sleep(30) + while loop sleep( chrono::milliseconds(30) + chrono::microseconds(500) ); return 0; }
ミリ秒以上は、WINAPI の Sleep() で処理を行ない、
ミリ秒未満の値は、while loop を使用して待ち処理を行っています。
ハイブリットってやつです。
実装側のコードがだいぶすっきりしました。
以下、sleep.hpp のコード。
#ifndef _KMT_EX_SLEEP_H_ #define _KMT_EX_SLEEP_H_ namespace kmt_ex{ namespace detail{ template <typename Rep, typename Period> void sleep_while_loop(const boost::chrono::duration<Rep, Period>& time){ boost::chrono::timer<> timer; while(timer.elapsed() < time); } #ifdef WINAPI void sleep_win_api_sleep(const boost::chrono::milliseconds& time){ Sleep(static_cast<DWORD>(time.count()) ); } #endif } // namespace detail #ifdef WINAPI /** ミリ秒以上の値は、WINAPI の Sleep() で待ち処理を行ないない、 ミリ秒未満の値は、while loop で待ち処理を行う */ template < typename Rep, typename Period > void sleep(const boost::chrono::duration<Rep, Period>& wait_time){ namespace chrono = boost::chrono; chrono::milliseconds ms = chrono::duration_cast<chrono::milliseconds>(wait_time); chrono::nanoseconds ns = wait_time - ms; detail::sleep_win_api_sleep(ms); detail::sleep_while_loop(ns); } #else /** while loop で待ち処理を行う */ template < typename Rep, typename Period > void sleep(const boost::chrono::duration<Rep, Period>& wait_time){ detail::sleep_while_loop(wait_time); } #endif } // namespace kmt_ex #endif