Мой случай выглядит следующим образом: программа использует два потока, назовем их «Отправитель» и «Получатель», потому что это механизм межпроцессного взаимодействия.
Поток «Отправитель» после отправки сообщения останавливаетсяпри условии, предоставленном std::condition_variable
и функцией .wait (Lock)
.Поток «Получатель» информирует ожидающий поток об ответе на его сообщение, используя .notify_one()
.
. Я доволен тем, как это работает, но я хочу добавить возможность обрабатывать время ожидания.
Я подготовил следующий класс (я хотел бы, чтобы он был универсальным, чтобы функция уведомления определялась из внешнего класса), но я уверен, что он может быть реализован лучше.Я хотел избежать большой загрузки процессора, поэтому я использовал std::this_thread::sleep_for
, но я полагаю, что его можно как-то заменить на std::this_thread::yield()
.Я хотел бы использовать, например, std::future_status
, но я не знаю, как это сделать.Как это можно улучшить?Я могу использовать стандартный c++11
или 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));
std::chrono::system_clock::time_point 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(LimitReached)
{
NotifyWaitingThreadFunction();
}
}
public:
Timer(int Milliseconds) : MsLimit(Milliseconds)
{
}
void StartTimer()
{
Stop = false;
LimitReached = false;
T = 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);
}
};