如何终止长时间运行的Qt Thread

时间:2012-02-07 00:05:58

标签: c++ multithreading qt qthread

我有一个线程应用程序,其中主线程是gui线程,而辅助线程是在嵌套for循环中进行主要计算的线程。现在的问题是如何终止辅助线程。当我按下GUI线程上的停止按钮时,它调用了辅助线程中的一个插槽,它将stop变量设置为true。这种技术的问题在于,在for循环中测试stop变量(如下所示)是不够的。因为如果在线程进入第三个for循环之后按下停止按钮,它将执行所有冗长的功能,然后它将检查停止标志。这就是为什么我们需要在执行其内容之前在每个函数中测试它,我认为这不是一个非常优雅的解决方案。 我不能在这个线程上调用terminate,因为这个线程分配了一些相当大的内存内存并且调用terminate会导致内存泄漏。

因此对于这样的场景,什么是终止线程和任何点的最佳方法?

以下代码框架只是为了让您了解我/我所谈论的内容

void run( ) {

     for(int i = 0; i < 4 && !stop; i++) {
          for(int j = 0; j < 3 && !stop; j++) {
               for(int k; k < 6 && !stop; k++) {
                    callA( );
                    callB( );
                    callC( );
                    callD( );
                    callE( );
                    callF( );
                    callF( );
                    callG( );
               }
          }
     }
}

callA( ) { callL( ); }

callB( ) { callM( ); }

callC( ) { callN( ); }

callD( ) { callO( ); }

callE( ) { callP( ); }

callF( ) { callQ( ); }

callF( ) { callR( ); }

callG( ) { callS( ); }

callL( ) { sleep(20); }

callM( ) { sleep(60); }

callN( ) { QProcess( ); }

callO( ) { sleep(30);}

callP( ) { QProcess( ); }

callQ( ) { }

callR( ) { sleep(60); }

callS( ) { QProcess( ); }

2 个答案:

答案 0 :(得分:1)

您可以在工作循环中调用QApplication :: processEvents()以允许线程接收事件。例如,一个事件可以是你的主要线程,调用一个槽来设置你检查的变量,看你是否应该中断你的工作。

//main thread calls this slot
void interupt_slot()
{
    stop_was_called = true;
}

void do_work()
{
   for(;;)
   {
       QApplication::processEvents();
       if(stop_was_called)
          break;

       //Work
   }

   //Exectution is over and the thread can be stopped etc
   emit its_over();

}

编辑:

虽然它不会中断线程的睡眠。如果主线程在线程休眠时调用interupt_slot()槽,则当sleep(n)结束时将调用槽。但你也可以通过在计时器上调用的插槽中进行工作来假装睡眠。

答案 1 :(得分:0)

您可以将函数包装在类中,并将这些类的对象列表存储在列表中。因此,调用您的函数将循环遍历此列表,并且您将只有一个代码位置来检查停止条件。 顺便说一下,为了避免在每个嵌套循环中停止查询,你可以使用goto或throw。 在C ++中,留下嵌套循环是goto唯一的“合法”用例。 关于投掷,B.Stroustrup优先于goto并鼓励将其用作控制结构。