QThread的正确使用方法

来源:互联网 发布:校园网络广播系统品牌 编辑:程序博客网 时间:2024/04/29 16:07
点击打开原文链接

qt自带的文档和例子中使用QThread都是继承QThread,然后重载run,
今天想在继承自QThread类中自定义一个槽,觉得对QThread的信号-槽的机制在多线程的情况下有些不清楚的地方,猜想QThread的槽并不是执行在QThread实例创建的子线程中,但我需要让槽执行在子线程中,查了一下资料,发现了QThread更好的使用方法。

如果不需要自定义槽,倒无所谓

第一种方法是在构造函数中调用 moveToThread(this)
代码如下
class MyThread : public QThread
{
public:
    MyThread()
    {
        moveToThread(this);
    }
 
   // void run();
 
signals:
    void progress(int);
    void dataReady(QByteArray);
 
public slots:
    void doWork();
    void timeoutHandler();
};

第二种方法,线程作为一种操作系统资源,不参与业务代码,推荐

class Producer : public QObject
{
Q_OBJECT
public slots:
void produce() { …emit produced(&data)…emit finished().. }
signals:
void produced(QByteArray *data);
void finished();
};

class Consumer : public QObject
{
Q_OBJECT
public slots:
void consume(QByteArray *data) { …emit consumed()…emit finished().. }
signals:
void consumed();
void finished();
};

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
// create the producer and consumer and plug them together
Producer producer;
Consumer consumer;
producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce()));
consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *)));

// they both get their own thread
QThread producerThread;
producer.moveToThread(&producerThread);
QThread consumerThread;
consumer.moveToThread(&consumerThread);

// start producing once the producer’s thread has started
producer.connect(&producerThread, SIGNAL(started()), SLOT(produce()));

// when the consumer is done, it stops its thread
consumerThread.connect(&consumer, SIGNAL(finished()), SLOT(quit()));
// when consumerThread is done, it stops the producerThread
producerThread.connect(&consumerThread, SIGNAL(finished()), SLOT(quit()));
// when producerThread is done, it quits the application
app.connect(&producerThread, SIGNAL(finished()), SLOT(quit()));

// go!
producerThread.start();
consumerThread.start();
return app.exec();
}

注意 
1) QObject::moveToThread()来改变它和它孩子们的线程亲缘关系,假如对象有父亲,它不能移动这种关系。
2) 在另一个线程(而不是创建它的那个线程)中delete QObject对象是不安全的。除非你可以保证在同一时刻对象不在处理事件。可以用QObject::deleteLater(),它会投递一个DeferredDelete事件,这会被对象线程的事件循环最终选取到。
3)QObject实例的创建与创建时的线程相关,可以引申出与创建时的线程的事件机制相关(信号-槽是此机制的一个高层封装)
原创粉丝点击