2012-06-28 45 views
3

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

我的基本设置如下:我有一个简单的类,我想在单独的线程中运行;实际上,我想运行这个类的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(); 

有时看起来,线程停止并销毁没有问题。其他时候,我得到上述错误。

任何指导将不胜感激。

感谢,

布莱恩

回答

4

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

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

请尝试更换:

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

有:

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