我正在尝试制作一个类运行器(以固定的时间频率运行一个类),它在另一个线程中运行一个类,并且可以从主线程控制(如暂停、恢复、停止)。
所以我想利用 C++11 的 Functor 和其他特性。但是我有一个奇怪的问题,传递给 Runner 的 Functor 的析构函数被调用了两次。
#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;
}
输出:
Fn
Runner
~Fn
~Runner
Running
Running
Running
Running
Running
~Fn
~Fn
如果我改变
Fn fn;
Runner runner(move(fn));
到
Runner runner(Fn());
该程序什么都没有,并且停滞不前。我试图禁用编译优化,没有任何变化。有什么解释吗?
我该如何解决这个问题或用其他方法做同样的事情?我应该像 std::async / std::thread 那样实现这个类吗?
更新到 Runner runner(Fn())
该语句作为函数声明被中断。
Runner runner((Fn()))
解决了问题。
感谢所有评论和回答。在查看rvalue之后,似乎我误解了从地面 0 引用 rvalue 的含义。我会尝试其他一些方法。
此问题的最终解决方案
#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[])
{
//vector<Fn> fns;
//fns.emplace_back(Fn());
Runner<Fn> runner;
return 0;
}
输出:
Fn
Runner
~Runner
Running
Running
Running
Running
Running
~Fn