Issue when scheduling tasks using clock() function

风流意气都作罢 提交于 2019-11-26 12:17:39

问题


I would like to schedule tasks at different time intervals: at 0.1 sec, 0.9s .... 2s etc I use the clock() C++ function that returns the number of ticks since the beginning of the simulation and I convert the ticks number to seconds using CLOCKS_PER_SEC but I have noticed that the task isn\'t scheduled when the instant is a float, but when it\'s an integer it does. Here the portion of the code responsible for the scheduling:

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 ; 

In that case, it doesn\'t work, but when I schedule the task to be done in 3 seconds for instance it works. Is it a problem of precision??


回答1:


If I was to implement some timer mechanism in C++, I would probably be using the std::chrono namespace together with 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();
        }
    }
}

To use, simply add events using events::add, and call events::timer a few times every second.

Example:

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();
}

The above example will print:

hello from foo
hello from bar::hello
Done!

One line will be printed every two second. After "Done!" the program will just loop forever, doing nothing.

Note that this program contains lots of C++11 functionality, but has been tested with GCC 4.4.5 and 4.7.1. VC++2010 unfortunately does not have the <chrono> header, but the VC++2012RC apparently have it.




回答2:


CLOCKS_PER_SEC is integer in your system. in other systems, it could be float too. put (float) near it too




回答3:


The problem could be because of your floating point comparison. This can provide unexpected results. Please avoid this.

Refer this link



来源:https://stackoverflow.com/questions/11865460/issue-when-scheduling-tasks-using-clock-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!