Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading QT->;如果线程正在消耗所有资源并且不允许执行插槽,如何终止线程_Multithreading_Qt_Qthread - Fatal编程技术网

Multithreading QT->;如果线程正在消耗所有资源并且不允许执行插槽,如何终止线程

Multithreading QT->;如果线程正在消耗所有资源并且不允许执行插槽,如何终止线程,multithreading,qt,qthread,Multithreading,Qt,Qthread,我正在开发Qt5.5,并创建了一个使用第三方库API的独立线程。此Api函数在执行时会消耗所有资源,不允许在该线程中执行任何其他函数 这个新线程以点击按钮开始,比如说“开始”,当我按下停止按钮时,我不知道如何停止或终止线程。下面是我的示例 threadWorking = new QThread(); workHeavy = new WorkingHard; workHeavy->moveToThread( threadWorking ); co

我正在开发Qt5.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。如果我使用terminate(),我还需要像我在Fifunction slotStopStream中指出的那样释放内存吗

请建议我根据id或其他信息终止线程

你不需要这样的建议。终止正在运行的线程会泄漏资源,并可能使进程处于损坏状态,例如,堆管理器的数据结构可能已损坏,或者其他全局状态可能已损坏不要强制终止线程-其他任何行为都是未定义的行为

我非常怀疑
g\u main\u loop\u run
是否“消耗”了所有资源。嗯,它正在忙着做某事,或者在等待事情的发生。毕竟,这是一个事件循环。:)调用
g\u main\u loop\u run
与在
QEventLoop
上调用
exec()
没有太大区别

您可以调用
g\u main\u loop\u quit
退出事件循环。如果它是
QEventLoop
,您可以从任何线程对其调用
quit
。但是我不确定
g\u main\u loop\u quit
是否是线程安全的,文档对此没有说明。唉,我们不必担心这一点:我们可以从工作线程本身调用它

我们将在循环的上下文中调用
g\u main\u loop\u 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);
}
应用于lambda的
+
运算符将其转换为函数指针。它使您不用定义独立函数

要结束循环,请从任何线程调用
quitLoop

请注意,如果您在Linux上,那么
QEventLoop
基于glib事件循环,您可以直接使用
QEventLoop
,而不是使用glib API

请建议我根据id或其他信息终止线程

你不需要这样的建议。终止正在运行的线程会泄漏资源,并可能使进程处于损坏状态,例如,堆管理器的数据结构可能已损坏,或者其他全局状态可能已损坏不要强制终止线程-其他任何行为都是未定义的行为

我非常怀疑
g\u main\u loop\u run
是否“消耗”了所有资源。嗯,它正在忙着做某事,或者在等待事情的发生。毕竟,这是一个事件循环。:)调用
g\u main\u loop\u run
与在
QEventLoop
上调用
exec()
没有太大区别

您可以调用
g\u main\u loop\u quit
退出事件循环。如果它是
QEventLoop
,您可以从任何线程对其调用
quit
。但是我不确定
g\u main\u loop\u quit
是否是线程安全的,文档对此没有说明。唉,我们不必担心这一点:我们可以从工作线程本身调用它

我们将在循环的上下文中调用
g\u main\u loop\u 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);
}
应用于lambda的
+
运算符将其转换为函数指针。它使您不用定义独立函数

要结束循环,请从任何线程调用
quitLoop



请注意,如果您在Linux上,那么
QEventLoop
是基于glib事件循环的,您可以直接使用
QEventLoop
,而不是使用glib API。

您的示例远远不够完整,也远远没有达到最低要求。也就是说,研究一下“线程取消”这个术语,以及为什么它会有问题。使用不同的流程可能是另一种选择。您应该显示您的
工作循环。这就是你应该把线程终止检测放在那里的地方,但是如果不知道你有什么样的代码,你很难给出建议。如果我使用terminate(),我还需要像我在函数slotStopStream中指出的那样释放内存吗?当然,如果您可以通过释放资源使内存更干净,那么您应该这样做。@samprat Thread terminate在那里结束线程,然后可能使例如数据结构处于无效状态。如果你真的没有其他方法告诉线程以可接受的延迟停止,那么只能将其作为最后的手段使用。你的示例远远没有按照要求完成和最小化。也就是说,研究一下“线程取消”这个术语,以及为什么它会有问题。使用不同的流程可能是另一种选择。您应该显示您的
工作循环。这就是你应该把线程终止检测放在那里的地方,但是如果不知道你有什么样的代码,你很难给出建议。如果我使用terminate(),我还需要像我在函数slotStopStream中指出的那样释放内存吗?当然,如果您可以通过释放资源使内存更干净,那么您应该这样做。@samprat Thread terminate在那里结束线程,然后可能使例如数据结构处于无效状态。如果你真的没有其他方法告诉线程以可接受的延迟停止,那么只能将其作为最后手段。非常感谢,伙计。我会试试,让你们知道我试过了,我发现当从不同的线程调用时,它会进入quitLoop,但视频不会stop@samprat
quitLoop
是否返回?我在lambda函数之后添加了调试stmt,并成功打印了它。非常感谢