【发布时间】:2014-07-16 19:03:14
【问题描述】:
我正在开发一个 Timer 类,该类在每个时间间隔调用一次函数。我注意到时钟运行速度稍慢,因为在设置时钟的等待量时,该函数没有考虑代码运行所需的量。我一直无法弄清楚如何测量函数调用期间经过的时间量,然后从间隔时间中减去它以产生准确的等待时间。
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
namespace Engine {
template<class return_type,class...arguments>
class Timer{
typedef std::function<return_type(arguments...)> _function_t;
typedef std::chrono::system_clock::time_point time_point;
typedef std::chrono::duration<size_t,std::micro> _duration;
public:
Timer(size_t interval,bool autoRun,_function_t function,arguments...args){
_function = function;
_interval = interval;
if (autoRun) {
Enable(args...);
}
}
~Timer(){
if (Running()) {
Disable();
}
}
void Enable(arguments...args){
if (!Running()) {
_running=true;
enable(_interval, _function, args...);
}
}
void Disable(){
if (Running()) {
_running=false;
delete _thread;
}
}
volatile bool const& Running()const{
return _running;
}
protected:
void enable(size_t interval,_function_t func,arguments...args){
_thread = new std::thread([&,func,interval,args...](){
while (_running) {
//measure time starting here
func(args...);
//end measurement here
//calculate interval- time elapsed
//use that value in the line below in place of "interval"
std::this_thread::sleep_for(std::chrono::microseconds(interval));
}
});
_thread->detach();
}
protected:
_function_t _function;
volatile bool _running;
size_t _interval;
std::thread* _thread;
};
}
如果有人对如何使用 std::chrono 库提出建议,请告诉我。请不要提升。我暂时不想处理它。
提前致谢。
编辑:
这是更新后的代码:
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <atomic>
namespace Engine {
template<class return_type,class...arguments>
class Timer{
typedef std::function<return_type(arguments...)> _function_t;
typedef std::chrono::system_clock::time_point time_point;
typedef std::chrono::duration<size_t,std::micro> _duration;
public:
Timer(size_t interval,bool autoRun,_function_t function,arguments...args){
_function = function;
_interval = interval;
if (autoRun) {
Enable(args...);
}
}
~Timer(){
if (Running()) {
Disable();
}
}
void Enable(arguments...args){
if (!Running()) {
_running=true;
enable(_interval, _function, args...);
}
}
void Disable(){
if (Running()) {
_running=false;
}
}
std::atomic_bool const& Running()const{
return _running;
}
protected:
void enable(size_t interval,_function_t func,arguments...args){
_thread =std::thread([&,func,interval,args...](){
std::chrono::duration<long long,std::nano> inter(interval);
auto _interval = std::chrono::microseconds(interval);
auto deadline = std::chrono::steady_clock::now();
while (_running) {
func(args...);
std::this_thread::sleep_until(deadline+=_interval);
}
});
_thread.detach();
}
protected:
_function_t _function;
std::atomic_bool _running;
size_t _interval;
std::thread _thread;
};
}
感谢您的帮助。
【问题讨论】:
-
(A)
volatile不能以可移植的方式避免_running上的数据竞争 - 您应该将其声明为std::atomic<bool>。 (B) 没有理由通过指针来保存_thread而不是直接将它放在类中。 -
@Casey 我会考虑到这一点。我将线程作为指针的原因是因为我在将它作为常规变量时遇到了一些麻烦。编辑:没关系我让它工作。谢谢
标签: c++ c++11 time timer chrono