この
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
Sをプッシュし、predicate
をfalse
に評価された場合、timer
からcallback
を削除します。 timer
オブジェクトは独自の有効期間を持ち、そのワーカースレッドは生きている間だけ存続します。
複数のjob
を1つのtimer
に含める理由は、1つのスレッドのみを使用して一緒に呼び出され、互いに同期するためです。
あなたはタイマー>万回秒を更新することを計画している場合を除き、mutex
心配<は1msの期間を持っているか、非常に時間がかかるcallback
Sを持っていません。
プログラムが他の処理をしている間に、タイマーを非同期で動作させたいのですか?次に、時間内のプロセスをスレッド内に置く必要があります。 –
@JasonLangもちろん、独自のスレッド – towi
'ping(100ms、callback)'の行に沿って何かをしたいのですか? –