马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
多线程实现
在Qt中,实现多线程编程有两种常见的方式,它们分别是通过继承QThread类和使用QObject::moveToThread()方法。
方式一:继承QThread类
通过继承QThread类并重写其run()方法,可以在新线程中实行特定的使命。
具体步调:
- 创建自界说线程类:继承QThread类,并重写run()方法。在run()方法中编写须要在新线程中实行的代码。
- 创建线程对象:在主线程中创建自界说线程类的实例。
- 启动线程:调用线程对象的start()方法启动线程。此时,Qt会创建一个新的线程,并在该线程中调用run()方法。
- 线程间通讯:可以通过信号和槽机制在主线程和子线程之间举行通讯。自界说线程类可以发射信号,主线程可以毗连这些信号到相应的槽函数,以处理处罚线程返回的数据或状态。
示例代码:
https://github.com/BinaryAI-1024/QtStudy/tree/master/thread/createThread1
- // mythread.h
- #include <QThread>
- #include <QDebug>
- class Mythread: public QThread{
- Q_OBJECT
- public:
- explicit Mythread(QObject *parent = nullptr);
- void run();
- };
复制代码- // mythread.cpp
- #include "Mythread.h"
- Mythread::Mythread(QObject *parent) : QThread(parent)
- {
- }
- void Mythread::run(){
- // 在新线程中执行的代码
- for (int i = 0; i < 5; ++i) {
- qDebug() << "Worker thread is running... (" << i << ")";
- QThread::sleep(1); // 模拟耗时操作
- }
- }
复制代码- //main.cpp
- #include <QCoreApplication>
- #include "Mythread.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- Mythread thread1;
- thread1.start();
- for (int i = 0; i < 5; ++i) {
- qDebug() << "Main thread is running... (" << i << ")";
- QThread::sleep(1); // 模拟耗时操作
- }
- thread1.wait(); // 等待直到thread1线程结束
- return a.exec();
- }
复制代码 运行效果:
- Main thread is running... ( 0 )
- Worker thread is running... ( 0 )
- Worker thread is running... ( 1 )
- Main thread is running... ( 1 )
- Worker thread is running... ( 2 )
- Main thread is running... ( 2 )
- Worker thread is running... ( 3 )
- Main thread is running... ( 3 )
- Main thread is running... ( 4 )
- Worker thread is running... ( 4 )
复制代码 优缺点分析:
- 优点:实现简单,得当须要在新线程中实行单一使命的场景。
- 缺点:
- 逼迫将业务逻辑与线程控制代码耦合在一起,倒霉于代码的复用和维护。
- 须要手动管理线程的生命周期,增长了代码的复杂性。
方式二: 使用QObject::moveToThread()方法
通过将QObject(或其子类)的实例移动到新线程中,可以在该线程中实行该对象的方法。这种方法更加机动,不须要继承QThread类。
具体步调:
- 创建工尴尬刁难象:界说一个继承自QObject的类,并在此中界说须要在新线程中实行的方法(槽函数)。
- 创建线程对象:在主线程中创建一个QThread实例。
- 移动对象到线程:调用工尴尬刁难象的moveToThread()方法,将其移动到新创建的线程中。
- 启动线程并调用槽函数:
- 调用线程对象的start()方法启动线程。
- 使用信号和槽机制,在主线程中发射信号,触发工尴尬刁难象在新线程中实行的槽函数。
- 线程间通讯:同样可以通过信号和槽机制在主线程和工作线程之间举行通讯。工作线程可以发射信号,主线程毗连这些信号到相应的槽函数,以处理处罚线程返回的数据或状态。
示例代码:
https://github.com/BinaryAI-1024/QtStudy/tree/master/thread/createThread2
- //myworker.h
- #include <QObject>
- class MyWorker : public QObject
- {
- public:
- explicit MyWorker(QObject *parent = nullptr);
- void working();
- };
复制代码- //myworker.cpp
- #include <QDebug>
- #include <QThread>
- #include "myworker.h"
- MyWorker::MyWorker(QObject *parent) : QObject(parent)
- {
- }
- void MyWorker:: working(){
- // 在新线程中执行的代码
- for (int i = 0; i < 5; ++i) {
- qDebug() << "Worker thread is running... (" << i << ")";
- QThread::sleep(1); // 模拟耗时操作
- }
- }
复制代码- //main.cpp
- #include <QCoreApplication>
- #include <QThread>
- #include <QDebug>
- #include "myworker.h"
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- QThread thread1;
- MyWorker worker;
- // 将 worker 对象移动到 thread1 线程中,以便 working 函数在 thread1 中执行
- worker.moveToThread(&thread1);
- // 连接 QThread 的 started 信号到 MyWorker 的 working 槽函数
- // 当 thread1 启动时,worker 的 working 函数会被调用
- QObject::connect(&thread1, &QThread::started, &worker, &MyWorker::working);
- // 启动 thread1 线程
- thread1.start();
- for (int i = 0; i < 5; ++i) {
- qDebug() << "Main thread is running... (" << i << ")";
- QThread::sleep(1); // 模拟耗时操作
- }
- thread1.wait();
- return a.exec();
- }
复制代码 运行效果:
- Main thread is running... ( 0 )
- Worker thread is running... ( 0 )
- Worker thread is running... ( 1 )
- Main thread is running... ( 1 )
- Worker thread is running... ( 2 )
- Main thread is running... ( 2 )
- Worker thread is running... ( 3 )
- Main thread is running... ( 3 )
- Main thread is running... ( 4 )
- Worker thread is running... ( 4 )
复制代码 优缺点分析:
- 优点:
- 将业务逻辑与线程控制代码分离,进步了代码的复用性和可维护性。
- 可以方便地在多个线程之间移动对象,实现复杂的线程间交互。
- 缺点:实现相对复杂一些,须要额外管理对象在新线程中的生命周期和信号槽毗连。
|