Created
August 5, 2016 20:31
-
-
Save alexkutsan/e81f86159cba9225dd29ffe79b8907f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <thread> | |
#include <iostream> | |
#include <condition_variable> | |
#include <chrono> | |
#include <mutex> | |
#include <atomic> | |
typedef std::function<void()> CallBack; | |
class Timer { | |
public: | |
Timer(int timeout, CallBack func) : | |
call_back_(func), | |
timeout_(timeout){} | |
virtual ~Timer() { | |
timer_thread_.join(); | |
} | |
virtual void Start() { | |
std::thread temp([&]{MainThread();}); | |
timer_thread_.swap(temp); | |
} | |
void DelayedCall(int timeout, CallBack func) { | |
std::unique_lock<std::mutex> lock_(timer_mutex_); | |
std::cv_status status = cv_.wait_for(lock_, std::chrono::seconds(timeout_)); | |
if (status == std::cv_status::timeout) { | |
func(); | |
} | |
} | |
virtual void MainThread() { | |
DelayedCall(timeout_, call_back_); | |
} | |
void Terminate() { | |
std::unique_lock<std::mutex> lock_(timer_mutex_); | |
cv_.notify_one(); | |
} | |
std::mutex timer_mutex_; | |
std::condition_variable cv_; | |
CallBack call_back_; | |
int timeout_; | |
std::thread timer_thread_; | |
}; | |
class LooperTimer : public Timer { | |
public: | |
LooperTimer(int timeout, CallBack func) : | |
Timer(timeout, func), | |
stop_flag_(false) {} | |
void Start() override { | |
stop_flag_ = false; | |
Timer::Start(); | |
} | |
void MainThread() override { | |
while(!stop_flag_) { | |
DelayedCall(timeout_, call_back_); | |
} | |
} | |
void Stop() { | |
stop_flag_= true; | |
Terminate(); | |
} | |
std::atomic<int> stop_flag_; | |
}; | |
int main() { | |
using namespace std::chrono_literals; | |
LooperTimer timer(1, []{ | |
static int x = 0; | |
std::cout << x++ << std::endl; | |
}); | |
timer.Start(); | |
std::this_thread::sleep_for(10s); | |
timer.Stop(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment