【发布时间】:2018-09-17 13:49:23
【问题描述】:
我有一个计时器,它将创建一个新线程并在调用通知函数之前等待计时器到期。它在第一次执行期间可以正常工作,但是当第二次启动计时器时,会抛出异常以尝试创建新线程。 调试输出显示前一个线程在尝试创建新线程之前已经退出。
Timer.hpp:
class TestTimer
{
private:
std::atomic<bool> active;
int timer_duration;
std::thread thread;
std::mutex mtx;
std::condition_variable cv;
void timer_func();
public:
TestTimer() : active(false) {};
~TestTimer() {
Stop();
}
TestTimer(const TestTimer&) = delete; /* Remove the copy constructor */
TestTimer(TestTimer&&) = delete; /* Remove the move constructor */
TestTimer& operator=(const TestTimer&) & = delete; /* Remove the copy assignment operator */
TestTimer& operator=(TestTimer&&) & = delete; /* Remove the move assignment operator */
bool IsActive();
void StartOnce(int TimerDurationInMS);
void Stop();
virtual void Notify() = 0;
};
Timer.cpp:
void TestTimer::timer_func()
{
auto expire_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(timer_duration);
std::unique_lock<std::mutex> lock{ mtx };
while (active.load())
{
if (cv.wait_until(lock, expire_time) == std::cv_status::timeout)
{
lock.unlock();
Notify();
Stop();
lock.lock();
}
}
}
bool TestTimer::IsActive()
{
return active.load();
}
void TestTimer::StartOnce(int TimerDurationInMS)
{
if (!active.load())
{
if (thread.joinable())
{
thread.join();
}
timer_duration = TimerDurationInMS;
active.store(true);
thread = std::thread(&TestTimer::timer_func, this);
}
else
{
Stop();
StartOnce(TimerDurationInMS);
}
}
void TestTimer::Stop()
{
if (active.load())
{
std::lock_guard<std::mutex> _{ mtx };
active.store(false);
cv.notify_one();
}
}
我的代码块在这里抛出了错误:
thread = std::thread(&TestTimer::timer_func, this);
在第二次执行期间。
具体来说,错误是从 move_thread 函数抛出的:_Thr = _Other._Thr;
thread& _Move_thread(thread& _Other)
{ // move from _Other
if (joinable())
_XSTD terminate();
_Thr = _Other._Thr;
_Thr_set_null(_Other._Thr);
return (*this);
}
_Thrd_t _Thr;
};
这是个例外:Unhandled exception at 0x76ED550B (ucrtbase.dll) in Sandbox.exe: Fatal program exit requested.
堆栈跟踪:
thread::move_thread(std::thread &_Other)
thread::operator=(std::thread &&_Other)
TestTimer::StartOnce(int TimerDurationInMS)
【问题讨论】:
-
谢谢汉斯,来自 C 我有一点要学习正确的 C++ 类构造。我明确删除了“特殊”成员函数并编辑了我的帖子以包含修改后的标题。尽管这根本没有改变堆栈跟踪。堆栈跟踪已添加到帖子中。
-
请注意,上面的代码已经过编辑以包含对问题的修复,特别是在尝试创建新线程之前未能加入线程。
标签: multithreading c++11