My case looks like this: The program uses two threads, let's call them "Sender" and "Recipient" because it is a mechanism of interprocess communication.
The "Sender" thread after sending the message stops at the condition provided by std::condition_variable and the .wait (Lock) function. The "Recipient" thread informs the waiting thread about the response to his message using .notify_one().
I'm happy with the way it works, but I want to add the ability to handle the timeout.
I prepared the following class (I would like it to be universal so the notification function is defined from the external class) but I'm sure that it can be implemented better. I wanted to avoid a lot of CPU usage, that's why I used std::this_thread::sleep_for, but I suppose that it can be somehow replaced with std::this_thread::yield(). I would like to use eg std::future_status, but I do not know how to do it. How can this be improved? I can use std c++11 or boost 1.55.
class Timer
{
private:
int MsLimit;
std::atomic<bool> Stop;
std::atomic<bool> LimitReached;
std::thread T;
std::mutex M;
std::function<void()> NotifyWaitingThreadFunction;
void Timeout()
{
std::unique_lock<std::mutex> Lock(M);
std::chrono::system_clock::time_point TimerStart = std::chrono::system_clock::now();
std::chrono::duration<long long, std::milli> ElapsedTime;
unsigned int T = 0;
do
{ std::this_thread::sleep_for(std::chrono::milliseconds(5));
TimerEnd = std::chrono::system_clock::now();
ElapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(TimerEnd - TimerStart);
T+=ElapsedTime.count();
if((T > MsLimit) && (!Stop))
{ LimitReached = true;
Stop = true;
}
}while(!Stop)
if(LmitReached)
{
NotifyWaitingThreadFunction();
}
}
public:
Timer(int Milliseconds) : MsLimit(Milliseconds)
{
}
void StartTimer()
{
Stop = false;
LmitReached = false;
Timer = std::thread(&Timer::Timeout,this);
}
void StopTimer()
{
std::unique_lock<std::mutex> Lock(M);
Stop = true;
LimitReached = false;
}
template<class T>
void AssignFunction(T* ObjectInstance, void (T::*MemberFunction)())
{
NotifyWaitingThreadFunction = std::bind(MemberFunction,ObjectInstance);
}
};
Aucun commentaire:
Enregistrer un commentaire