I am trying to create a runner class (run a class with a fixed time frequency) that runs the class on another thread and can be controlled (e.g. pause, resume, stop) from the main thread.
So I want to use C ++ 11 Functor and other functions. But I have a strange problem, the Functor destructor passed to Runner was called twice.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
class Runner {
public:
typedef function<bool()> fn_t;
Runner(fn_t &&fn) : fn_(move(fn)), thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
fn_t fn_;
thread thread_;
static void Thread(Runner &runner) {
while (runner.fn_()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliumseconds(1));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (++count < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
Fn fn;
Runner runner(move(fn));
return 0;
}
outpus:
Fn
Runner
~Fn
~Runner
Running
Running
Running
Running
Running
~Fn
~Fn
and if I change
Fn fn;
Runner runner(move(fn));
to
Runner runner(Fn());
the program does nothing and stalls. I tried to disable optimization compilation, nothing changes. Any explanation?
How can I fix this or do something in another method? Should I implement this class as std :: async / std :: thread?
Upgrade to Runner runner(Fn())
This statement was interrupted as a function declaration.
Runner runner((Fn())) solved the problem.
. rvalue , rvalue 0. .
#include <iostream>
#include <chrono>
#include <thread>
#include <vector>
using namespace std;
template<typename T, typename... Args>
class Runner {
public:
Runner(Args&&... args) :
t(forward<Args>(args)...),
thread_(Thread, ref(*this)) {
cout << "Runner" << endl;
}
~Runner() {
cout << "~Runner" << endl;
thread_.join();
}
private:
T t;
thread thread_;
static void Thread(Runner &runner) {
while (runner.t()) {
cout << "Running" << endl;
this_thread::sleep_for(chrono::milliseconds(100));
}
}
};
class Fn {
public:
Fn() : count(0) {
cout << "Fn" << endl;
}
~Fn() {
cout << "~Fn" << endl;
}
bool operator()() {
return (count++ < 5);
}
private:
int count;
};
int main (int argc, char const* argv[])
{
Runner<Fn> runner;
return 0;
}
outpus:
Fn
Runner
~Runner
Running
Running
Running
Running
Running
~Fn