环境情况:使用的是thread c++11线程和qt的定时器
报错:
QObject::~QObject: Timers cannot be stopped from another thread
主要原因:
1.开启了一个事件循环线程处理消息类型,但是有一种消息类型需要关闭资源,这就导致当前线程调用xxxapi,把自己的资源关闭了,但是函数还没执行完。
2.stop同时涉及到定时器关闭,导致直接程序崩溃
std::shared_ptr<IjkMediaPlayer> mp = this->mp_;
while{switch(xxx){
case FFP_MSG_NETWORK_URL_ERROR:
emit sig_showTips(Toast::ERROR, (char *)msg.obj);
stop(); //关闭all 资源 ,涉及到当前位置mp,定时器。 bug所在
break;
}
if (msg.obj)msg.free_l(msg.obj);}mp.reset();
LOG(DEBUG) << "message_loop leave";
解决方案
原理:在子线程中使用 QMetaObject::invokeMethod()
函数来间接地停止定时器。这种方式可以将停止定时器的操作切换回主线程执行。也就是说资源释放是主线程干的。就不会阻塞调用stop!
QMetaObject::invokeMethod(this, "stop", Qt::QueuedConnection);
std::shared_ptr<IjkMediaPlayer> mp = this->mp_;
while{switch(xxx){
case FFP_MSG_NETWORK_URL_ERROR:
emit sig_showTips(Toast::ERROR, (char *)msg.obj);
//实现子线程关闭定时器
QMetaObject::invokeMethod(this, "stop", Qt::QueuedConnection);
break;
}
if (msg.obj)msg.free_l(msg.obj);}mp.reset();
LOG(DEBUG) << "message_loop leave";