C ++(11)定时器:累积到空闲状态

时间:2016-10-25 19:30:54

标签: c++ c++11 condition-variable

我正面临一个相当基本的问题,我只想用C ++实现(11是好的)只使用标准的库。

假设一个函数" Message()"这可以被称为任何给定的次数,在我想要触发动作的特定时间之后没有被调用。例如:

Message();
Message();
Message();
Message();
sleep(10); <-- the idle time triggers an action 
Message(); 

希望这是有道理的。

到目前为止,我实现这一点的方法是使用async while循环和一个条件变量的组合,每次消息进入时我都会发出脉冲。一旦等待CV超时,我就采取行动。

在伪代码中:

void Message(){
  unique_lock ul(M);
  new_message = false;
  CV.notify();
}

...

future = std::async([]{ 
  do {
    unique_lock ul(M);
    new_message = false;
    got_message_within_time = CV.wait_for(ul, 20ms, new_message==true);
  } while got_message_within_time;
  // Got a timeout here...
  time_to_take_action(); 
});

...

Message()
Message() 
Message()
sleep(10)

我不相信这是最优雅的解决方案,任何人都有更好的建议吗?总而言之,我想要实现的基本陈述是:&#34;一旦我停止打电话给你,做一些事情&#34;

欢迎任何帮助/建议

谢谢!

1 个答案:

答案 0 :(得分:0)

我使用的方法类似于你所做的,但我让监控线程运行。

#include <chrono>
#include <iostream>
#include <thread>

using namespace std::chrono;

time_point<steady_clock> lastMessage(steady_clock::now());
bool shutdown(false);

void InactiveMessageLoop(){
    while(!shutdown){
        if((steady_clock::now() - lastMessage) > milliseconds(1000)){
            std::cout << "Are you still there?" << std::endl;
        }
        std::this_thread::sleep_for(milliseconds(1000));
    }
    std::cout << "No hard feelings." << std::endl;
}

void Message(){
   lastMessage = steady_clock::now();
   // do stuff;
}

int main(){
    std::thread MessageThread(InactiveMessageLoop);

    Message();
    Message();

    std::this_thread::sleep_for(milliseconds(5000));

    Message();
    Message();

    shutdown = true;

    if(MessageThread.joinable()) MessageThread.join();

    return 0;
}

或者你可以考虑发送一个信号,但是通过调用消息检查功能来交换你的代码可能同样有效,因为将业务逻辑放在信号函数中被认为是不好的做法。

编辑:我在最后添加了连接。