1.相关定义
1.1多线程
即分时利用CPU,宏观上让所有线程一起执行 ,也叫并发
- QThreadPool线程池
- QMutex互斥锁:保证任意时刻只有一个线程进行访问
1.2线程五种状态
- 创建:生成线程对象,没有调用该对象的Start方法
- 就绪 :调用了该对象的Start方法,但是线程调度程序没有把该线程设置为当前线程,此时处于就绪状态
- 运行 :线程调度程序将就绪状态的线程设置为当前线程,此时处于运行状态,开始执行run函数里面的内容
- 阻塞 :线程正在运行的时候,被暂停(通常是为了等待某项资源就绪,之后再继续运行) sleep suspend wait
- 死亡:run()方法结束,或者调用stop之后,线程死亡,无法使用start再次使其进入就绪状态
1.3多线程配合信号和槽:
连接时第五个参数,为线程间信号和槽的通讯方法
- 直接连接,槽运行在发出信号的线程 DirectConnection
- 队列连接,槽运行在接收信号的生存线程中,依赖于事件循环 QueuedConnection
- 自动选择,根据发出信号线程和信号接收对象的生存线程,自动选择直接连接和 队列连接
2.使用
2.1使用concurrent 高级线程API
#include <QtConcurrent>//在pro文件中添加concurrent
// threadPool.waitPorDone(); //等待所有的线程结束
QtConcurrent::run([=](){ //中括号用于捕获
//实际运行在子线程中
qDebug()<<"QtConcurrent:"<<QThread::currentThread();
QFile file(filepath); //创建文件路径
file.open(QIODevice::WriteOnly);
file.write(data);
file.waitForBytesWritten(30*1000);
});
QtConcurrent::run(&threadPool,[&](){ //使用&捕获锁
//操作之前,先锁住---保证当前线程在访问当中,其他线程等着
mutex.lock();
//操作之后,就进行解锁
mutex.unlock();
});
Sender sender; //信号的发送方(生存线程即主线程)
QtConcurrent::run([&](){
Receive receiver; //接收方是自己开启的一个子线程
//转移线程操作
receiver.moveToThread(qApp->thread());//由线程转移到主线程
QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive); //创建连接默认采用自动连接选择直接连接可以省略不写但是必须注
// 采用直接连接的方式:槽运行发出的信号的线程,这里发出信号的线程就是主线程,机槽运行在主线程中
QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive,Qt::DirectConnection);//直接连接与上面连接方式是一致的
//采用队列的方式联机,槽运行在接收信号对象的生存线程,依赖于事件循环,槽运行在子线程中
QObject::connect(&sender,&Sender::mySignal,&receiver,&Receive::onReceive,Qt::QueuedConnection);//队列连接
QEventLoop eventLoop;
eventLoop.exec();//启动事件循环--=-直连不需要事件循环,如果是队列连接需要进行事件循环
});
QThread::sleep(1);
emit sender.mySignal(); //发射信号
return a.exec();
3.QThread类主要接口
- bool isFinished() 线程是否结束
- bool isRunning 线程是否正在运行
- Priority priority 返回线程的优先级
- void setPriority(Priority priority) 设置线程的优先级
- void exit(int returnCode=0)退出线程的事件循环,退出码为returnCode ,0表示成功退出,否则表示有错误
- bool wait(unsigned long time) 阻止线程执行,直到线程结束(从run()函数返回),或等待时间超过time毫秒
- void quit 退出线程的事件循环,并返回代码0,等效于exit(0)
注意:
1.主线程与子线程占用不同的内存空间
2.避免死锁:lock和unlock配对使用