std::thread 计时器
Timer with std::thread
我正在使用计时器 class 在不同的线程上执行操作,下面的示例代码是从另一个 SO 问题 HERE
复制的
#include <thread>
#include <chrono>
#include <functional>
class Timer
{
public:
~Timer();
Timer() noexcept;
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
public:
void start(const Interval& interval, const Timeout& timeout);
void stop();
private:
std::thread mThread; /** Timer thread */
bool mRunning = false; /** Timer status */
};
实现时附上会出现问题的注释:
Timer::~Timer()
{
}
Timer::Timer() noexcept
{
}
void Timer::start(const Interval& interval, const Timeout& timeout)
{
mRunning = true;
mThread = std::thread([&]()
{
while (mRunning == true)
{
std::this_thread::sleep_for(interval);
// std::abort will be called here
timeout();
}
});
}
void Timer::stop()
{
mRunning = false;
mThread.join();
}
测试计时器的示例:
#include <iostream>
int main()
{
Timer tm;
tm.start(std::chrono::milliseconds(1000), []
{
std::cout << "Hello!" << std::endl;
});
std::this_thread::sleep_for(std::chrono::seconds(4));
tm.stop();
}
我无法理解为什么在 lambda 中执行 std::function
时调用 std::abort
,我该如何解决这个问题?
您的 start
函数的参数通过引用传递。在您的 lambda 中,您通过引用捕获它们。当您开始调用该 lambda 时,您捕获的所有内容都已被销毁,因此您导致了未定义的行为。
此外,请确保使用 atomic<bool>
而不是常规的 bool
:
#include <thread>
#include <chrono>
#include <functional>
#include <cstdio>
#include <atomic>
class Timer {
public:
~Timer() {
if (mRunning) {
stop();
}
}
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval, const Timeout &timeout) {
mRunning = true;
mThread = std::thread([=]() {
while (mRunning) {
std::this_thread::sleep_for(interval);
timeout();
}
});
}
void stop() {
mRunning = false;
mThread.join();
}
private:
std::thread mThread{};
std::atomic_bool mRunning{};
};
int main() {
Timer tm;
tm.start(std::chrono::milliseconds(1000), [] {
std::puts("Hello!");
});
std::this_thread::sleep_for(std::chrono::seconds(4));
}
P.S。你可能想根据这个想法的发展方向来研究协程。
我正在使用计时器 class 在不同的线程上执行操作,下面的示例代码是从另一个 SO 问题 HERE
复制的#include <thread>
#include <chrono>
#include <functional>
class Timer
{
public:
~Timer();
Timer() noexcept;
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
public:
void start(const Interval& interval, const Timeout& timeout);
void stop();
private:
std::thread mThread; /** Timer thread */
bool mRunning = false; /** Timer status */
};
实现时附上会出现问题的注释:
Timer::~Timer()
{
}
Timer::Timer() noexcept
{
}
void Timer::start(const Interval& interval, const Timeout& timeout)
{
mRunning = true;
mThread = std::thread([&]()
{
while (mRunning == true)
{
std::this_thread::sleep_for(interval);
// std::abort will be called here
timeout();
}
});
}
void Timer::stop()
{
mRunning = false;
mThread.join();
}
测试计时器的示例:
#include <iostream>
int main()
{
Timer tm;
tm.start(std::chrono::milliseconds(1000), []
{
std::cout << "Hello!" << std::endl;
});
std::this_thread::sleep_for(std::chrono::seconds(4));
tm.stop();
}
我无法理解为什么在 lambda 中执行 std::function
时调用 std::abort
,我该如何解决这个问题?
您的 start
函数的参数通过引用传递。在您的 lambda 中,您通过引用捕获它们。当您开始调用该 lambda 时,您捕获的所有内容都已被销毁,因此您导致了未定义的行为。
此外,请确保使用 atomic<bool>
而不是常规的 bool
:
#include <thread>
#include <chrono>
#include <functional>
#include <cstdio>
#include <atomic>
class Timer {
public:
~Timer() {
if (mRunning) {
stop();
}
}
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval, const Timeout &timeout) {
mRunning = true;
mThread = std::thread([=]() {
while (mRunning) {
std::this_thread::sleep_for(interval);
timeout();
}
});
}
void stop() {
mRunning = false;
mThread.join();
}
private:
std::thread mThread{};
std::atomic_bool mRunning{};
};
int main() {
Timer tm;
tm.start(std::chrono::milliseconds(1000), [] {
std::puts("Hello!");
});
std::this_thread::sleep_for(std::chrono::seconds(4));
}
P.S。你可能想根据这个想法的发展方向来研究协程。