提问人:newww 提问时间:11/8/2023 最后编辑:newww 更新时间:11/8/2023 访问量:102
调用 terminate 后退出 C++ 线程,没有活动异常
C++ thread exits after calling terminate called without an active exception
问:
我创建了一个用于创建和删除计时器的计时器类,并且我有固定数量的计时器。一些计时器在完成回调功能后会重新启动。在某些情况下,我可能需要删除计时器。有了这个逻辑,我想出了以下代码:
计时器.cpp:
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <vector>
#include <algorithm>
#include <iostream>
#include <thread>
#include <atomic>
class Timer
{
public:
Timer();
~Timer();
void Start( const uint8_t pipeId, const uint32_t msPeriod);
void Stop();
private:
void TimerCallbacktimer( const uint8_t pipeId);
std::chrono::milliseconds msPeriod_;
uint8_t pipeId_;
std::thread thread_;
std::condition_variable cv_;
std::mutex mutex_;
std::atomic<bool> stop_waiting_{false};
std::atomic<bool> done_{false};
};
void Timer::TimerCallbacktimer( const uint8_t pipeId)
{
//callback function left empty on purpose
}
void Timer::Start( const uint8_t pipeId, const uint32_t msPeriod)
{
pipeId_ = pipeId;
msPeriod_ = std::chrono::milliseconds(msPeriod);
if (done_) //if the thread was already created and expired join it before restarting the thread
{
thread_.join();
done_.store(false);
}
thread_ = std::thread
{
[this]()
{
std::unique_lock<std::mutex> lck(mutex_);
cv_.wait_for(lck, msPeriod_, [this]() { return stop_waiting_.load(); });
if (not stop_waiting_)
{
TimerCallbacktimer(pipeId_);
done_.store(true);
}
}
};
}
void Timer::Stop()
{
stop_waiting_.store(true);
cv_.notify_one();
}
Timer::Timer()
{
}
Timer::~Timer()
{
if (thread_.joinable())
{
thread_.join();
}
}
std::vector<Timer> TimerArray(30);
std::mutex timerMutex;
void CreateTimer( const uint8_t slot , const int32_t pipeId, const uint32_t msPeriod )
{
std::unique_lock<std::mutex> lock(timerMutex);
TimerArray[slot].Start(pipeId, msPeriod);
}
void DeleteTimer( const uint8_t slot )
{
std::unique_lock<std::mutex> lock(timerMutex);
TimerArray[slot].Stop();
}
int main(int argc, char const *argv[])
{
CreateTimer(3, 3, 300);
CreateTimer(4, 3, 100);
DeleteTimer(4);
CreateTimer(3, 3, 100);
// sometimes I start the same timer immediately after it has called its callback function
CreateTimer(3, 3, 100);
return 0;
}
由于我确实有固定数量的计时器,因此我确实会在有
我面临的问题是有时我会得到一个错误。我似乎无法弄清楚为什么会弹出错误。我脑海中突然出现的东西基本上是我在计时器过期后立即再次启动计时器,我需要在回调函数中进行一些清理以准备它再次启动?另外,我应该在回调函数完成时加入线程吗?terminate called without an active exception
答:
1赞
463035818_is_not_an_ai
11/8/2023
#1
正如 molbdnilo 的评论中提到的,当计时器已经在运行但尚未运行时,您不会处理调用的情况。Start
done_
要重新启动计时器,您可以向 发出信号,它(并重置为其初始值):stop_waiting_
join
done_
//if (done_) //if the thread was already created and expired join it before restarting the thread
// if the thread was already created, join it!
if (thread_.joinable()){
stop_waiting_.store(true);
thread_.join();
done_.store(false);
}
现场演示。
代码中的崩溃是由联接之前导致的。它与这个非常简化的代码存在相同的问题:thread_ = std::thread ...
int main() {
std::thread t{[](){
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}};
t = std::thread([](){}); // -> terminates
}
有关详细信息,我建议您访问以下 cppreference :std::thread::operator=(thread&& other)
如果仍然有一个关联的正在运行的线程(即 ),则调用 .否则,将 的状态分配给 并设置为默认构造状态。
*this
joinable() == true
std::terminate()
other
*this
other
在此调用之后,等于调用之前的值,并且不再表示执行的线程。
this->get_id()
other.get_id()
other
评论
0赞
newww
11/9/2023
解决方案奏效了,但我不得不将 stop_waiting_.store(true) 更改为 stop_waiting_.store(false)。因为它带来了僵局
0赞
463035818_is_not_an_ai
11/9/2023
@newww嗯......太取消了等待的呼叫。否则必须等待计时器过期。也许我错过了什么,没有看到僵局,但很高兴它有所帮助。stop_waiting_.store(true);
wait_for
stop_waiting_
true
thread_.join();
评论
join
join
done_