我正在開發一個計時器類以在不同的執行緒上執行操作,下面的示例代碼是另一個 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();
}
我無法理解為什么std::abort在執行std::functioninside lambda 時被呼叫,我該如何解決這個問題?
uj5u.com熱心網友回復:
函式的引數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));
}
PS你可能想根據這個想法去研究協程。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/450266.html
下一篇:原子交換兩個指標的值
