Qthread - 关闭线程的麻烦

时间:2012-06-28 21:13:12

标签: qthread

在过去的几天里,我一直在尝试使用QThreads的新首选方法,而无需继承QThread。我遇到的麻烦是当我尝试关闭我创建的一组线程时。我经常得到一个“线程仍在运行时被销毁”的消息(如果我在调试模式下运行,我也会得到一个Segmentation Fault对话框)。我的代码很简单,我试图按照我在互联网上找到的例子。

我的基本设置如下:我有一个简单的类,我想在一个单独的线程中运行;实际上,我想运行这个类的5个实例,每个实例都在一个单独的线程中。我有一个简单的对话框,带有一个按钮来启动每个线程,还有一个按钮来停止每个线程(10个按钮)。当我单击其中一个“开始”按钮时,会创建一个新的测试类实例,创建一个新的QThread,调用一个movetothread来获取该测试类对象...也是,因为我有一对在测试类中需要移动到线程的其他成员,我使用这些其他项目再调用movetothread几次。请注意,其中一个项目是QUdpSocket,虽然这可能没有意义,但我想确保套接字可以这种方式移动到一个单独的线程...我还没有测试套接字在此时的线索。

线程的启动似乎都运行正常。当我使用linux top命令查看线程是否已创建并正在运行时,它们会按预期显示。

当我开始停止线程时会出现问题。我随机(或看似随机)得到上述错误。

要在单独的线程中运行的类:

// Declaration
class TestClass : public QObject
{
Q_OBJECT
public:
explicit TestClass(QObject *parent = 0);
QTimer m_workTimer;
QUdpSocket m_socket;

Q_SIGNALS:
void finished();

public Q_SLOTS:
void start();
void stop();
void doWork();

};

// Implementation
TestClass::TestClass(QObject *parent) :
QObject(parent)
{

}

void TestClass::start()
{
  connect(&m_workTimer, SIGNAL(timeout()),this,SLOT(doWork()));
  m_workTimer.start(50);
}

void TestClass::stop()
{
  m_workTimer.stop();
  emit finished();
}

void TestClass::doWork()
{
int j;
for(int i = 0; i<10000; i++)
  {
    j = i;
  }
}

在我的主应用程序中,代码调用以启动第一个线程(每个其他线程都存在类似的代码):

mp_thread1 = new QThread();
mp_testClass1 = new TestClass();
mp_testClass1->moveToThread(mp_thread1);
mp_testClass1->m_socket.moveToThread(mp_thread1);
mp_testClass1->m_workTimer.moveToThread(mp_thread1);

connect(mp_thread1, SIGNAL(started()), mp_testClass1, SLOT(start()));
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(quit()));
connect(mp_testClass1, SIGNAL(finished()), mp_testClass1, SLOT(deleteLater()));
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater()));
connect(this,SIGNAL(stop1()),mp_testClass1,SLOT(stop()));

mp_thread1->start();

同样在我的主应用程序中,当为特定线程(在本例中为线程1)单击停止按钮时,将调用此代码:

emit stop1();

有时似乎线程被停止并被销毁而没有问题。其他时候,我得到上述错误。

非常感谢任何指导。

谢谢,

布赖恩

1 个答案:

答案 0 :(得分:4)

http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

“最后,为了防止令人讨厌的崩溃,因为线程在删除时还没有完全关闭,我们将线程的完成()(不是worker!)连接到它自己的deleteLater()槽。导致线程只有在完全关闭后才被删除。“

请尝试更换:

    connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater()));

使用:

    connect(mp_thread1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater()));