我正在研究Qt 5.5并创建了一个使用第三方库API的独立线程。此Api函数在执行时会占用所有资源,并且不允许任何其他函数在该线程中执行。
这个新线程首先点击按钮说“开始”,当我按下停止按钮时,我只是不知道如何停止或杀死线程。以下是我的示例
threadWorking = new QThread();
workHeavy = new WorkingHard;
workHeavy->moveToThread( threadWorking );
connect( threadWorking, SIGNAL( started() ), workHeavy, SLOT( slotStartStream() ) );
connect( workHeavy, SIGNAL( sigStopStream() ), threadWorking, SLOT( quit() ) );
connect( workHeavy, SIGNAL( sigStopStream() ), workHeavy, SLOT(deleteLater() ) );
connect( threadWorking, SIGNAL( finished() ), threadWorking, SLOT(deleteLater() ) );
connect( workHeavy, SIGNAL( sigStartStream() ), this, SLOT( slotTrueStreamRun() ) );
connect( workHeavy, SIGNAL( sigStopStream() ), this, SLOT( slotFalseStreamRun() ) );
connect( this, SIGNAL( sigMopsCamStopCmd() ), workHeavy, SLOT(slotStopStream() ) );
threadWorking->start();
Also// void WorkingHard::slotStartStream()
{
g_main_loop_run( gloop ); // this consumes all resources.
}
void WorkingHard::slotStopStream()
{
// clean up mess
g_main_loop_quit( gloop );
gst_element_set_state (pipeline, GST_STATE_NULL);
// g_main_loop_quit( gloop );
releaseMemory();
}
请建议我根据id或别的东西杀死线程。有一点很清楚,当函数运行时,我无法进入线程内部。
人们建议使用终止。如果我使用terminate(),我仍然需要释放内存,因为我指向了函数slotStopStream ??
答案 0 :(得分:0)
请建议我根据id或别的东西杀死线程。
你不需要这样的建议。终止正在运行的线程会泄漏资源,并可能使您的进程处于损坏状态 - 例如堆管理器的数据结构可能已损坏,或者其他全局状态可能已损坏。 不要强制终止线程 - 其他任何未定义的行为。
我非常怀疑@last_object
是"消费"所有资源。好吧,它忙于做某事,或者正在等待事情发生。毕竟,这是一个事件循环。 It's even documented :)拨打g_main_loop_run
与在g_main_loop_run
上拨打exec()
没有太大区别。
您可以调用QEventLoop
退出事件循环。如果是g_main_loop_quit
,您可以从任何线程调用QEventLoop
。但是,我不确定quit
是否是线程安全的,文档是关于它的。唉,我们不必担心:我们可以从工作线程本身调用它。
我们会在循环的上下文中调用g_main_loop_quit
。 lambda的主体将在工作线程中运行并将导致循环退出:
g_main_loop_quit
应用于lambda的class WorkingHard : public QObject {
Q_OBJECT
GMainLoop * gloop;
....
};
/// This method is thread-safe
void WorkingHard::quitLoop() {
auto context = g_main_loop_get_context(gloop);
g_main_context_invoke(context, +[](gpointer ptr) -> gboolean {
g_main_loop_quit((GMainLoop*)ptr);
return FALSE;
}), (gpointer)gloop);
}
运算符将其转换为函数指针。它使您无法定义独立功能。
要结束循环,请从任何线程调用+
。
请注意,如果您使用的是Linux,那么quitLoop
基于glib事件循环,您可以直接使用QEventLoop
,而不是使用GLib apis。