待ち処理
WINAPI の Sleep() に chrono::duration で定義されている単位で渡したかったのでラップしました。
ついでにミリ秒未満なら while ループで待ち処理も実装。
#include <boost/chrono.hpp> #include <boost/chrono/timer.hpp> #include <boost/utility/enable_if.hpp> #include <Windows.h> #include "sleep.hpp" 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 return 0; }
それぞれの単位の時に呼ばれる処理は上記の通り。
Windows.h がインクルードされていない場合は、while ループの方で待ち処理を行います。
while ループで待つ場合は、CPUが全力駆動するので重くなります。
C/C++ って、Sleep() 以外の待ち処理ってないんでしょうか。
UNIX 系やスレッド周りの待ち処理ってどうやって実装してるんだろう。
ところで、今回は、Windows.h のインクルードの有無を WINAPI の定義で判断してるけど
これで合ってるかどうかは不明。
以下、sleep.hpp の中身。
#ifndef _KMT_EX_SLEEP_H_ #define _KMT_EX_SLEEP_H_ namespace kmt_ex{ namespace detail{ #ifdef WINAPI using boost::enable_if; using boost::ratio_less; using boost::ratio_greater_equal; /** Period < milliseconds の場合に呼ばれる */ template<typename Period> void sleep_impl( const boost::chrono::nanoseconds& wait_time, typename enable_if<ratio_less<Period, boost::milli> >::type* = 0 ){ boost::chrono::timer<> timer; while(timer.elapsed() < wait_time); } /** Period >= milliseconds の場合に呼ばれる */ template<typename Period> void sleep_impl( const boost::chrono::milliseconds& wait_time, typename enable_if<ratio_greater_equal<Period, boost::milli> >::type* = 0 ){ Sleep(static_cast<DWORD>(wait_time.count()) ); } #else /** Windows.h をインクルードしていない場合は、while loop で待ち処理 */ template<typename T> void sleep_impl(const boost::chrono::nanoseconds& wait_time){ boost::chrono::timer<> timer; while(timer.elapsed() < wait_time); } #endif } // namespace detail /** 待ち処理 */ template < typename Rep, typename Period > void sleep(const boost::chrono::duration<Rep, Period>& wait_time){ detail::sleep_impl<Period>(wait_time); } } // namespace kmt_ex #endif