QThread - 关闭线程出现问题

3
在过去的几天里,我一直在尝试使用不需要子类化QThread的新方法来使用QThreads。但是当我尝试关闭一组我创建的线程时,我遇到了困难。我经常会收到“在线程仍在运行时已销毁”消息(如果我在调试模式下运行,我还会收到一个分段错误对话框)。我的代码非常简单,并且我已经尝试遵循我能在互联网上找到的示例。

我的基本设置如下:我有一个简单的类,我想在单独的线程中运行;实际上,我想要在五个不同的线程中运行这个类的五个实例。我有一个简单的对话框,其中包含一个按钮来启动每个线程和一个按钮来停止每个线程(共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();

有时候,线程似乎可以正常停止和销毁,而没有任何问题。但是有时候,我会遇到上述错误。
如果您能提供任何指导,将不胜感激。
谢谢,
Bryan
1个回答

4

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

"最后,为了防止因线程在删除时尚未完全关闭而导致的崩溃,我们将线程(而不是worker)的finished()连接到其自身的deleteLater()槽中。这样可以确保在线程完全关闭后才进行删除操作。"

请尝试替换:

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

使用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接