c++ - 使用 clock() 函数安排任务时出现问题

标签 c++ scheduled-tasks precision clock

我想在不同的时间间隔安排任务:0.1 秒、0.9 秒 .... 2 秒等 我使用 clock() C++ 函数返回自模拟开始以来的滴答数,并使用 CLOCKS_PER_SEC 将滴答数转换为秒数,但我注意到当瞬间为 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 秒内完成时,它就起作用了。是不是精度问题??

最佳答案

如果我要在 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);  // TODO: Do some "real" work here instead...
    events::timer();
}

上面的例子会打印:

hello from foo
hello from bar::hello
Done!

每两秒打印一行。在"Done!"之后该程序将永远循环,什么都不做。

请注意,此程序包含许多 C++11 功能,但已使用 GCC 4.4.5 和 4.7.1 进行了测试。不幸的是,VC++2010 没有 <chrono> header ,但 VC++2012RC 显然有它。

关于c++ - 使用 clock() 函数安排任务时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11865460/

相关文章:

c++ - MDI Qt 应用程序中的链接器错误 : undefined reference to qInitResources_mdi()

java - 将自定义系统日期设置为计划程序

c# - 在 NopCommerce 中创建自定义任务

math - float 学有问题吗?

java - 为什么 HBase 中的 Bytes.toBytes() 无法返回我在我的情况下搜索的最后一行?

c++ - 并非所有工作项目都在使用 opencl

c++ - 如何使用 boost::read_graphml 读取图域属性?

c++ - 使用模板和/或 constexpr 在编译时构建函数

c++ - C++ 中 float 据类型的精度

windows - 在另一个任务运行后运行一个任务