Qt------QThread

一、基于信号量的线程同步

信号量通常用于保护一定数量的相同资源,如数据采集时的双缓冲区

  • acquire(int n)尝试获得N个资源,如果没有那么多资源,线程将阻塞直到有n个资源可用
  • release(int n)释放n个资源,如果信号量的资源已全部可用之后再releas(),就可以创建更多的资源,增加可用资源的个数
  • int available()返回当前信号量可用资源个数,这个数不可能为负数,如果为0就说明当前没有资源可用
  • bool tryAcquire(int n=1)尝试获取n个资源,不成功时不阻塞线程

二、多线程

1.方法1

1.1.创建一个线程类的子类,让其继承 QT 中的线程类 QThread

class Generate : public QThread

explicit Generate(QObject *parent = nullptr);

protected: 
   void run() override;





Generate::Generate(QObject *parent) : QThread(parent)
{

}


qDebug() << "生成随机数的线程地址: " << QThread::currentThread();
    QVector<int> list;
    QElapsedTimer time;
    time.start();
    for(int i=0;i<m_num;i++)
    {
        list.push_back(qrand()%10000);
    }
    int milsec = time.elapsed();//从启动或重启用时
    qDebug() << "生成" << m_num << "个随机数总共用时: " << milsec << "毫秒";

1.2.重写父类的 run () 方法,在该函数内部编写子线程要处理的具体的业务流程

1.3.在主线程中创建子线程对象,new 一个就可以了

1.4.启动子线程,调用 start () 方法

1.5对线程的析构

 connect(this,&MainWindow::destroyed,this,[=](){
        gen->quit();
        gen->wait();
        gen->deleteLater(); // delete gen;

        bubble->quit();
        bubble->wait();
        bubble->deleteLater();

        quick->quit();
        quick->wait();
        quick->deleteLater();
    });

2.方法2

2.1创建一个新的类,让这个类从 QObject 派生

class Generate:public QObject{}

2.1在这个类中添加一个公共的成员函数,函数体就是我们要子线程中执行的业务逻辑

public:
  void working();

2.3在主线程中创建一个 QThread 对象,这就是子线程的对象

QThread *t1=new QThread;

2.4在主线程中创建工作的类对象(千万不要指定给创建的对象指定父对象)

Generate *gen=new Generate;

2.5将 MyWork 对象移动到创建的子线程对象中,需要调用 QObject 类提供的 moveToThread() 方法

gen->moveToThread(t1);

2.6启动子线程,调用 start(), 这时候线程启动了,但是移动到线程中的对象并没有工作

t1->start();

2.7调用 MyWork 类对象的工作函数,让这个函数开始执行,这时候是在移动到的那个子线程中运行的

connect(ui->btnStart,&QPushButton::clicked,gen,&Generate::working);

2.8 同上1.5删除线程

3.方法3

3.1先创建任务

//​添加到线程池中的每一个任务都需要是一个 QRunnable 类型,因此在程序中需要创建子类继承 QRunnable 这个类,同时如果有使用信号槽进行数据传递,需要继承QObject
class Generate:public QObject,public QRunnable
//-------------------------------------------------------------------
Generate::Genrate(QObject *parent):QObject(parent),QRunnable(){

//任务执行完毕,该对象自动销毁
setAutoDelete(true);
}

​

3.2 重写run方法,在这个函数中编写要在线程池中执行的任务

3.3线程池初始化,设置最大线程池数

QThreadPool::globalInstance()->setMaxThreadCount(4);

3.4 创建工作线程对象

Generate *genThread=new Generate;

3.5将工作对象扔进线程池启动

QThreadPool::globalInstance()->start(genThread);

// 在子类中必须要重写的函数, 里边是任务的处理流程
[pure virtual] void QRunnable::run();

// 参数设置为 true: 这个任务对象在线程池中的线程中处理完毕, 这个任务对象就会自动销毁
// 参数设置为 false: 这个任务对象在线程池中的线程中处理完毕, 对象需要程序猿手动销毁
void QRunnable::setAutoDelete(bool autoDelete);
// 获取当前任务对象的析构方式,返回true->自动析构, 返回false->手动析构
bool QRunnable::autoDelete() const;



// 获取和设置线程中的最大线程个数
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);

// 给线程池添加任务, 任务是一个 QRunnable 类型的对象
// 如果线程池中没有空闲的线程了, 任务会放到任务队列中, 等待线程处理
void QThreadPool::start(QRunnable * runnable, int priority = 0);
// 如果线程池中没有空闲的线程了, 直接返回值, 任务添加失败, 任务不会添加到任务队列中
bool QThreadPool::tryStart(QRunnable * runnable);

// 线程池中被激活的线程的个数(正在工作的线程个数)
int QThreadPool::activeThreadCount() const;

// 尝试性的将某一个任务从线程池的任务队列中删除, 如果任务已经开始执行就无法删除了
bool QThreadPool::tryTake(QRunnable *runnable);
// 将线程池中的任务队列里边没有开始处理的所有任务删除, 如果已经开始处理了就无法通过该函数删除了
void QThreadPool::clear();

// 在每个Qt应用程序中都有一个全局的线程池对象, 通过这个函数直接访问这个对象
static QThreadPool * QThreadPool::globalInstance();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值