我想以不同的时间间隔安排任务:0.1秒,0.9秒...... 2秒等 我使用clock()C ++函数返回自模拟开始以来的刻度数,并使用CLOCKS_PER_SEC将刻度数转换为秒,但我注意到当Instant是float时,任务没有被调度,但是当它是一个整数。这里负责调度的代码部分:
float goal = (float) clock() / CLOCKS_PER_SEC + 0.4 ; // initially (float) clock() / CLOCKS_PER_SEC = 0 ;
if ((float) clock() / CLOCKS_PER_SEC == goal)
do stuff ;
在这种情况下,它不起作用,但是当我计划在3秒内完成任务时,例如它可以工作。这是一个精度问题吗?
答案 0 :(得分:13)
如果我要在C ++中实现一些计时器机制,我可能会将std::chrono
namespace与std::priority_queue
一起使用。
#include <functional>
#include <queue>
#include <chrono>
#include <sys/time.h> // for `time_t` and `struct timeval`
namespace events
{
struct event
{
typedef std::function<void()> callback_type;
typedef std::chrono::time_point<std::chrono::system_clock> time_type;
event(const callback_type &cb, const time_type &when)
: callback_(cb), when_(when)
{ }
void operator()() const
{ callback_(); }
callback_type callback_;
time_type when_;
};
struct event_less : public std::less<event>
{
bool operator()(const event &e1, const event &e2) const
{
return (e2.when_ < e1.when_);
}
};
std::priority_queue<event, std::vector<event>, event_less> event_queue;
void add(const event::callback_type &cb, const time_t &when)
{
auto real_when = std::chrono::system_clock::from_time_t(when);
event_queue.emplace(cb, real_when);
}
void add(const event::callback_type &cb, const timeval &when)
{
auto real_when = std::chrono::system_clock::from_time_t(when.tv_sec) +
std::chrono::microseconds(when.tv_usec);
event_queue.emplace(cb, real_when);
}
void add(const event::callback_type &cb,
const std::chrono::time_point<std::chrono::system_clock> &when)
{
event_queue.emplace(cb, when);
}
void timer()
{
event::time_type now = std::chrono::system_clock::now();
while (!event_queue.empty() &&
(event_queue.top().when_ < now))
{
event_queue.top()();
event_queue.pop();
}
}
}
要使用,只需使用events::add
添加事件,然后每秒呼叫events::timer
几次。
示例:
void foo()
{
std::cout << "hello from foo\n";
}
void done()
{
std::cout << "Done!\n";
}
struct bar
{
void hello()
{ std::cout << "Hello from bar::hello\n"; }
};
auto now = std::chrono::system_clock::now();
bar b;
events::add(foo, now + std::chrono::seconds(2));
events::add(std::bind(&bar::hello, b), now + std::chrono::seconds(4));
events::add(done, now + std::chrono::seconds(6));
while (true)
{
usleep(10000);
events::timer();
}
以上示例将打印:
hello from foo hello from bar::hello Done!
每两秒打印一行。在"Done!"
之后,程序将永远循环,什么都不做。
请注意,此程序包含许多C ++ 11功能,但已经过GCC 4.4.5和4.7.1的测试。遗憾的是,VC ++ 2010没有<chrono>
标题,但VC ++ 2012RC显然有它。
答案 1 :(得分:0)
CLOCKS_PER_SEC在您的系统中是整数。在其他系统中,它也可能是浮动的。把(浮动)放在它附近
答案 2 :(得分:0)
问题可能是因为你的浮点比较。这可以提供意外的结果。请避免这种情况。
参考this链接