Qt之QThread随记

这是一篇随记,排版什么的就没有那么好了:)

首先要知道,一个线程在资源分配完之后是以某段代码为起点开始执行的,例如STL内的std::thread,POSIX下的pthread等,都是以函数加其参数之后在新线程内调用运行的,但是,Qt的却进行了一个封装,要使用Qt的QThread,核心思想就是将对象在线程内创建或移入线程中,之后通过那些在线程内的对象的信号和槽方式与其他线程进行交互,这里就衍生出来了两种写法(虽然核心思想都是一样的):

  • 第一种:
...
class myThread:
    public QThread{
private:
    myObj1 obj1;        //注意,这两个对象都要继承自QObject,
    myObj2 obj2;        //否则不能使用信号和槽,而且没有moveToThread这个方法
public:
    myThread(){
        obj1.moveToThread(this);
        obj2.moveToThread(this);
    }
    void run() override{
        myObject3 obj3; //此时该对象本省就是线程内的对象了,不需要继承自QObject
                        //但是缺点在于,要以多线程的方式
                        //即在当前线程内使用该对象的方法,只能在当前函数内调用
                        //这实际上是与Qt的开发思想是相悖的,Qt的多线程开发思想就是
                        //借助信号和槽的机制,以当前线程的槽队列来进行线程内的对象
                        //与其他线程内交互
        ...
        ...
        exec();         //进入事件循环等待信号的发出
    }
public slots:
    void slot1(){
        ...
    }
};
...

其实不难想,QThread的线程入口就是他的run函数,置于其他的,遵从一个原则:

所有的资源(包括信号和槽函数),都是属于创建该对象的那个线程的,所以不难想到在当前myThread中的任何一个信号和槽都将会在默认情况下在创建这个对象的那个线程内执行,比如:

int main(int a,char **b){
    QtCoreApplication a(a,b);
    QTimer tmer;
    myThread mTh;
    QObject::connect(&tmer,"timeout()",&mTh,"slot1()");
    tmer.start(1s);
    return a.exec()
}

很明显,在QTimer触发timeout()信号的时候,槽slot1始终在当前线程(主程)内调用

接下来就要隆重介绍两种主要的信号,槽的连接方式了:

Qt::QueueConnection和Qt::DirectConnection

第一种就是将当前的信号放入槽所属的对象的事件循环队列内

第二种是直接在当前线程内调用槽函数,直接调用自然可以知道,执行槽函数的线程就是当前的信号所属的线程

通常默认情况下,连接方式是Qt:AutoConnection,该方式判断,如果信号和槽所属的是一个线程,那么此时使用Qt::DirectConnection,否则使用Qt::QueueConnection

但是注意:

在上面那个例子中,connect不论以何种方式进行信号槽的调用,都将是在主线程内调用的,援引在之前已经说到了,myThread对象的创建线程就是主线程,所以信号和槽均属于主线程,不存在跨线程的情况

  • 第二种:
...
int main(int a,char **b){
    QtCoreApplication a(a,b);
    QThread sgThread;
    myObj1 obj1;
    obj1.moveToThread(&sgThread);
    QTimer tmer;
    QObject::connect(&tmer,"timeout()",&obj1,...,Qt::DirectConnection);
        //此时obj1的槽会被主线程调用
    QObject::connect(&tmer,"timeout()",&obj1,...);
        //此时默认Queue,所以会在sgThread所创建的那个中调用
    tmer.start(1s);
    return a.exec();
}
...

实际上,第一种和第二种是一模一样的思路和方法,只是moveToThread的位置不同,但是要注意:moveToThread不是线程安全的,换句话说,moveToThread只能是在当前线程和参数所指线程对象不同的情况下才能正确调用,因此第一种方式和第二种方式是一致的.

原文地址:https://www.cnblogs.com/A001/p/10947888.html

时间: 2024-08-06 09:23:24

Qt之QThread随记的相关文章

Qt之QThread(深入理解)

简述 前面,我们介绍了QThread常用的两种方式: worker-object 子类化QThread 下面,我们首先来看看子类化QThread在日常中的应用. 简述 子类化QThread 在主线程中更新UI 正常结束线程 更多参考 一般情况下,QThread进行耗时操作的同时会与UI进行交互,比如:显示进度.旋转等待...进行友好型的交互,让用户知道当前的操作. 子类化QThread 我们以更新进度条为例,来模拟一个耗时操作,并分享我们有可能在此过程中遇到的问题及解决办法. 首先,我们定义一个

解析Qt中QThread使用方法

本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用QThread,随便用google一搜,就能搜出大量结果出来.无怪乎Qt的开发人员 Bradley T. Hughes 声嘶力竭地喊you are-doing-it-wrong 和众多用户一样,初次看到这个时,感到 Bradley T. Hughes有 些莫名奇妙,小题大作.尽管不舒服,当时还是整理过一篇博客QThread 的使

Qt多线程-QThread

版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThread     本文地址:http://techieliang.com/2017/12/592/ 文章目录 1. 介绍  1.1. 线程优先级  1.2. 线程休眠 2. 基本使用  2.1. 建立QThread子类法  2.2. moveToThread方法 3. 线程同步  3.1. QMutex互斥量  3.2. QMutexLocker  3.3. QReadWr

QT下QThread学习(二)

学习QThread主要是为了仿照VC下的FTP服务器写个QT版本.不多说,上图. FTP服务器的软件结构在上面的分析中就已经解释了,今天要解决的就是让每一个客户端的处理过程都可以按一个线程来单独跑.先给出上面3个类的cpp文件,再给出现象. 1.QListenSocket类 1 #include "qlistensocket.h" 2 #include <QTcpSocket> 3 #include <QDebug> 4 5 QListenSocket::QLi

Qt线程—QThread的使用--run和movetoThread的用法

Qt使用线程主要有两种方法: 方法一:继承QThread,重写run()的方法 QThread是一个非常便利的跨平台的对平台原生线程的抽象.启动一个线程是很简单的.让我们看一个简短的代码:生成一个在线程内输出"hello"并退出的线程. // hellothread/hellothread.h class HelloThread : public QThread { Q_OBJECT private: void run(); }; 我们从QThread派生出一个类,并重新实现run方法

Qt QThread必须要了解的几个函数

概述 如果想对Qt中的QThread有个更加深刻的了解,必须要知道这几个重要的函数,现在就一一介绍下. 函数介绍 属性 返回值 函数体 功能 static QThread * QThread::currentThread() 返回当前线程的指针,静态函数. static Qt::HANDLE QThread::currentThreadId() 返回当前线程的句柄,静态函数 static bool QThread::isFinished() const 如果线程执行结束,返回true,否则返回f

QT多线程[转]

Qt作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功能.为了满足用户构造复杂图形界面系统的需求,Qt提供了丰富的多线程编程支持.从 2.2 版本开始,Qt主要从下面三个方面对多线程编程提供支持:一.构造了一些基本的与平台无关的线程类:二.提交用户自定义事件的 Thread-safe方式:三.多种线程间同步机制,如信号量,全局锁.这些都给用户提供了极大的方便.不过,在某些情况下,使用定时器机制能够比利用 Qt本身的多线程机制更方便地实现所需要的功能,同时也避免了

从pthread 到QThread

该文出自:http://www.civilnet.cn/bbs/topicno/78430 使用线程技术进行应用编程的意义在gemfield的文章<从进程到线程>中已经介绍过了,我们就直奔主题:Linux上的线程开发以及Qt对线程的封装(Linux平台部分).Linux上的线程API使用的是pthread库,我们来粗略认识下pthread. 要在程序中使用pthread线程,究竟会用到哪几部分的功能呢? 1.创建线程是必须的吧,pthread_create(): 2.设置线程的属性也是需要的吧

QT线程(一):线程类

线程之间共享数据,但又单独执行: QT线程QThread是平台无关的: 通常主线程从main开始执行,而在主线程中创建其他线程,其他线程派生于QThread: 1.线程优先级 总共8个优先级:线程优先级从上到下越来越高. Constant Value Description QThread::IdlePriority 0 scheduled only when no other threads are running. QThread::LowestPriority 1 scheduled le