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/perl/11.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
C++ QThread终止和关联_C++_Multithreading_Qt - Fatal编程技术网

C++ QThread终止和关联

C++ QThread终止和关联,c++,multithreading,qt,C++,Multithreading,Qt,此示例用于测试QThread。主要目标是能够在专用线程中运行一个耗时的阻塞方法,并且 能够在任意点终止和重新启动线程。阻塞方法是我们无法控制的第三方库。我知道Qt的文档不鼓励使用QThread::terminate,但目前我看不到任何其他方法 下面是在专用线程中运行所需代码的PSEDOO示例。基本上有一种方法需要10-15分钟来处理。没有逻辑位置可以添加moveToThread以在QThread::termination上将关联性带回主线程,或者添加executiong processEvent

此示例用于测试QThread。主要目标是能够在专用线程中运行一个耗时的阻塞方法,并且 能够在任意点终止和重新启动线程。阻塞方法是我们无法控制的第三方库。我知道Qt的文档不鼓励使用QThread::terminate,但目前我看不到任何其他方法

下面是在专用线程中运行所需代码的PSEDOO示例。基本上有一种方法需要10-15分钟来处理。没有逻辑位置可以添加moveToThread以在QThread::termination上将关联性带回主线程,或者添加executiong processEvent以处理QThread::quit方法

void run()
{
  // initiate variables
  thirdparty lib(var1, var2);
  int res = lib.execute(var3, var4, var6);
  // handle result and exit
}
在Windows7上使用Qt4.7

运行代码将生成此输出

Test::doWork thread: QThread(0x219e960) 
Test::started thread: QThread(0x239bce8)
Test::doTerminate thread: QThread(0x239bce8) 
Test::doWork thread: QThread(0x239bce8) 
QObject::moveToThread: Current thread (0x219e960) is not the object's thread (0x239bce8). Cannot move to target thread (0x239bd20)
第二次执行Test::doWork方法时,moveToThread API失败。这似乎是因为测试实例与另一个线程有亲缘关系,而该线程在此时终止。然后如何更改关联性

终止和重新启动QThread的建议方法是什么?是否需要删除测试实例

守则

#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <QDebug>
#include "Worker.h"
#include "Windows.h"

class Test : public QObject
{
  Q_OBJECT
  QThread* m_thread;
  int      m_state;

public:
    Test() : m_thread(0), m_state(3) { }

public slots:
    void doWork()
    {
      qDebug() << "Test::doWork thread:" << QObject::thread();
      if (!m_thread)
      {
        m_thread = new QThread();
        QObject::moveToThread(m_thread);
        QObject::connect(m_thread, SIGNAL(started()), this, SLOT(started()));
        QObject::connect(m_thread, SIGNAL(finished()), this, SLOT(finished()));
        QObject::connect(m_thread, SIGNAL(terminated()), this, SLOT(terminated()));
        m_thread->start();
      }
    }

    void started()
    {      
      qDebug() << "Test::started thread:" << QObject::thread();
      Sleep(60);
    }

    void finished()
    {
      qDebug() << "Test::finished thread:" << QObject::thread();
    }

    void terminated()
    {
      qDebug() << "Test::terminated thread:" << QObject::thread();
    }

    void doTerminate()
    {
      qDebug() << "Test::doTerminate thread:" << QObject::thread();
      QObject::disconnect(m_thread);
      m_thread->terminate();
      m_thread->wait();
      m_thread = NULL;
    }

    int state()
    {
      return m_state;
    }
};

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  Test test;

  test.doWork();
  Sleep(10);

  test.doTerminate();
  Sleep(10);

  test.doWork();
  return a.exec();
}

不使用terminate,您可以调用更可接受的函数quit。

您可以在杀死m_线程之前将测试对象推回到主线程,但这样做似乎有点奇怪。如果必须重新启动,为什么要终止线程?还应该考虑将m_线程的信号连接到它的插槽。现在,您正在将m_thread值设置为0,但我看不到您在任何地方销毁该对象。第三方方法是使用多个参数执行的。如果参数不正确,您可能希望终止执行,然后使用不同的参数重新启动。如何将测试对象推回到主线程?this->moveToThreadQApplication::instance->thread;QThread::quit docs状态告诉线程的事件循环退出,返回代码为0 success。这是中断当前事件还是等待它完成然后退出?我希望它在事件循环中完成正在处理的任何事件,然后干净地退出。感谢您的回复。这种方法的问题是,正在处理的事件是一项耗时的任务,它将占用系统资源并生成不再需要的数据。因此,我选择了一种更有力的方法。为什么不将一个信号连接到测试类中的一个插槽来停止任务呢?如果任务处于一个常量while循环中,阻止消息被发送,那么每隔一段时间调用QApplication::processEvents一次。问题是任务很忙,基本上只有一个阻塞呼叫,可能需要10分钟才能完成。没有插入QApplication::processEvents的位置。这个设计超出了我的控制。