ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 使用clock()函数调度任务时出现问题

2019-09-17 23:05:27  阅读:242  来源: 互联网

标签:c scheduled-tasks precision clock


我想以不同的时间间隔安排任务:0.1秒,0.9秒…… 2秒等
我使用clock()C函数返回自模拟开始以来的滴答数,并使用CLOCKS_PER_SEC将滴答数转换为秒,但我注意到当瞬间为浮点数时,任务未被调度,但是它是一个整数.这里负责调度的代码部分:

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 namespacestd::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!

每两秒打印一行.在“完成!”之后程序将永远循环,什么都不做.

请注意,该程序包含许多C 11功能,但已经过GCC 4.4.5和4.7.1的测试.不幸的是,VC 2010没有< chrono>标题,但VC 2012RC显然有它.

标签:c,scheduled-tasks,precision,clock
来源: https://codeday.me/bug/20190917/1810214.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有