我正在尝试使用经典方法实现基本计时器:start()和stop()。我正在使用带有std :: thread和std :: chrono的c ++ 11。
我创建并启动了一个显示“Hello!”的Timer对象。每一秒,然后与其他线程我试图停止计时器,但我不能。计时器永不停止。
我认为问题在于th.join()[*]在线程完成之前停止执行,但是当我删除th.join()行时,程序显然在计时器开始计数之前完成。
所以,我的问题是如何在不停止其他线程的情况下运行线程?
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class Timer
{
thread th;
bool running = false;
public:
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval,
const Timeout &timeout)
{
running = true;
th = thread([=]()
{
while (running == true) {
this_thread::sleep_for(interval);
timeout();
}
});
// [*]
th.join();
}
void stop()
{
running = false;
}
};
int main(void)
{
Timer tHello;
tHello.start(chrono::milliseconds(1000),
[]()
{
cout << "Hello!" << endl;
});
thread th([&]()
{
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
});
th.join();
return 0;
}
输出:
Hello!
Hello!
...
...
...
Hello!
答案 0 :(得分:8)
在Timer::start
中,您在th
中创建一个新主题,然后立即join
使用th.join()
。实际上,start
在产生的线程退出之前不会返回。当然,它永远不会退出,因为在start
返回...
在您打算等待它完成之前,不要join
一个线程。在这种情况下,设置stop
之后running = false
可能是正确的位置。
另外 - 虽然它不是不正确的 - 但是没有必要在main
中建立另一个线程来呼叫this_thread::sleep_for
。您可以使用主线程执行此操作:
int main()
{
Timer tHello;
tHello.start(chrono::milliseconds(1000), []{
cout << "Hello!" << endl;
});
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
}
答案 1 :(得分:1)
而不是将join
置于start
running = false
之后stop
。然后stop方法将在返回之前有效地等待线程完成。