Как установить функцию повторяющегося таймера?

Есть ли простой способ установить регулярно встречающуюся функцию таймера с C ++ / stdlib? Я хотел бы избавиться от цикла:

using namespace std::chrono; // literal suffixes
auto tNext = steady_clock::now();
while (<condition>) {
std::this_thread::sleep_until(tNext);
tNext = tNext + 100ms;
...

Эта функция будет работать в своем собственном потоке.

0

Решение

Я думаю, что вы хотите, это

int i = 10;
auto pred = [i]() mutable {return i--;};
auto print = []{cout << "." << endl;};

timer t{500ms};
t.push({print, pred});  //asynchronously prints '.' 10 times within 5s

//do anything else

Предполагая, что производительность не критична и таймер не часто обновляется, следующее должно обеспечить достаточную функциональность.

#include<functional>
#include<vector>
#include<thread>
#include<utility>
#include<chrono>
#include<mutex>
#include<atomic>

class timer final
{
public:
using microseconds = std::chrono::microseconds;

using predicate = std::function<bool ()>;
using callback = std::function<void ()>;
using job = std::pair<callback, predicate>;

explicit timer(microseconds t) : done{false}, period{t}
{
std::lock_guard<std::mutex> lck(mtx);

worker = std::thread([this]{
auto t = std::chrono::steady_clock::now();
while(!done.load())
{
std::this_thread::sleep_until(t);
std::lock_guard<std::mutex> lck(mtx);
t += period;
for(auto it = jobs.begin(); it != jobs.end();)
{
if(it->second())
it++->first();
else
it = jobs.erase(it);
}
}
});
}

~timer()
{
done.store(true);
worker.join();
}

void set_period(microseconds t)
{
std::lock_guard<std::mutex> lck(mtx);
period = t;
}
void push(const callback& c)
{
std::lock_guard<std::mutex> lck(mtx);
jobs.emplace_back(c, []{return true;});
}
void push(const job& j)
{
std::lock_guard<std::mutex> lck(mtx);
jobs.push_back(j);
}

private:
std::mutex mtx;
std::atomic_bool done;
std::thread worker;

std::vector<job> jobs;
microseconds period;
};

timer звонки ранее нажал callbackпериодически и когда predicate оценивает falseудаляет callback от timer, timer Объект имеет свое собственное время жизни, и его рабочий поток будет жить только до тех пор, пока он жив.

Причина, по которой вы хотели бы иметь несколько jobс в одном timer это так, что они будут вызываться вместе, используя только один поток и быть синхронизированы друг с другом.

Не беспокойся о mutex если вы не планируете обновлять таймер> 10000 раз в секунду, имейте период <1 мс или очень много времени callbacks.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]