Qt线程创建的4种方式

继承QThread

继承QThread,通过重写虚函数void QThread::run()实现自己想做的操作,start()运行线程。

QThread::run()有一个默认的实现。这个默认实现其实是简单地调用QThread::exec()函数,而这个函数其实是开始了一个事件循环。

class WorkerThread : public QThread//继承QThread
{
      Q_OBJECT
      void run() Q_DECL_OVERRIDE {//
          QString result;
          /* ... here is the expensive or blocking operation ... */
          emit resultReady(result);
      }
  signals:
      void resultReady(const QString &s);
};


 WorkerThread *workerThread = new WorkerThread(this);//创建线程
 workerThread->start();//开启线程

继承QRunnable

继承QRunnable,使用QThreadPool::globalInstance()->start() 运行它.

class Task : public QRunnable
{
  //Q_OBJECT   注意了没有Q_OBJECT,Qrunnable不是QObject的子类。
public:
    void run()
    {
        /* 线程的相关代码 */
    }
};


Task runObj;
//QThreadPool::globalInstance()获得全局线程池
//start()将一个QRunnable对象放入QThreadPool的执行队列
//一旦有线程可用,线程池将会选择一个QRunnable对象,然后在那个线程开始执行.
QThreadPool::globalInstance()->start(&runObj);

要真正执行一个QRunnable对象,我们需要使用QThreadPool类。顾名思义,这个类用于管理一个线程池。通过调用QThreadPool::start(runnable)函数,我们将一个QRunnable对象放入QThreadPool的执行队列。一旦有线程可用,线程池将会选择一个QRunnable对象,然后在那个线程开始执行。所有 Qt 应用程序都有一个全局线程池,我们可以使用QThreadPool::globalInstance()获得这个全局线程池;与此同时,我们也可以自己创建私有的线程池,并进行手动管理。

需要注意的是,QRunnable不是一个QObject,因此也就没有内建的与其它组件交互的机制。为了与其它组件进行交互,你必须自己编写低级线程原语,例如使用 mutex 守护来获取结果等。

QThreadPool会自动的清理我们新建的Qrunnable对象.

moveToThread

使用moveToThread这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,
如果moveToThread里执行的函数没执行完,你是无法通过quit来结束的,必须使用第一种方法:最歹毒的一招mthread->terminate()强制退出。

为什么要使用moveToTread()呢。
eg:moveToThread对比传统子类化Qthread更灵活,仅需要把你想要执行的代码放到槽,movetothread这个object到线程,然后拿一个信号连接到这个槽就可以让这个槽函数在线程里执行。可以说,movetothread给我们编写代码提供了新的思路,当然不是说子类化qthread不好,只是你应该知道还有这种方式去调用线程。

class Dummy:public QObject 
{ 
    Q_OBJECT 
public: 
    Dummy(QObject* parent=0):QObject(parent){} 
public slots: 
    void emitsig() 
    { 
        emit sig(); 
    } 
signals: 
    void sig(); 
}; 

class Object:public QObject 
{ 
    Q_OBJECT 
public: 
    Object(){} 
public slots: 
    void slot() 
    { 
        qDebug()<<"from thread slot:" <<QThread::currentThreadId(); 
    } 
}; 


int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    qDebug()<<"main thread:"<<QThread::currentThreadId(); 
    QThread thread; 
    Object obj; 
    Dummy dummy; 
    obj.moveToThread(&thread); 
    // 这里的slot()函数,相当于run()函数的作用,slot()函数将在线程中执行
    QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot())); 
    thread.start(); 
    dummy.emitsig(); 
    return a.exec(); 
}

QtConcurrent::run()

QtConcurrent::run()启动一个线程来执行一个函数.
QtConcurrent是一个命名空间而不是一个类,因此其中的所有函数都是命名空间内的全局函数。
QtConcurrent::run是个模板函数

void printMes(QString mes)
{
       qDebug()<<"pprintMes thread : "<<QThread::currentThreadId();
       qDebug()<<mes;
}

int main(int argc, char *argv[])
{
       QCoreApplication a(argc, argv);
       qDebug()<<"mainthread :"<<QThread::currentThreadId();

       QString mes = "hello world";
       QtConcurrent::run(printMes,mes);

       returna.exec();
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值