QT - >如果线程占用所有资源并且不允许执行槽,如何杀死线程

时间:2016-02-02 23:57:41

标签: multithreading qt qthread

我正在研究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 ??

1 个答案:

答案 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。