什么叫营销型网站,网站建设大概多少钱,网站建设可行性研究报告,国外网站建设公司Qt中的多线程 目录
1 为什么需要多线程 2 Qt中使用多线程的一些注意事项 3 QThread类 3.1 QThread类的主要接口 3.2 线程的优先级 4 通过继承QThread类实现多线程 5 从QObject类进行派生实现多线程 5 小结 1 为什么需要多线程 在现代化的程序设计开发中#xff0c;多进程… Qt中的多线程 目录
1 为什么需要多线程 2 Qt中使用多线程的一些注意事项 3 QThread类 3.1 QThread类的主要接口 3.2 线程的优先级 4 通过继承QThread类实现多线程 5 从QObject类进行派生实现多线程 5 小结 1 为什么需要多线程
在现代化的程序设计开发中多进程、多线程是经常采用的设计方式。在Qt程序中默认线程主线程为窗口线程当Qt程序在某些情况下需要处理复杂逻辑的时候比如需要较长时间的网络操作、耗时的数据处理等可能会占用很长的时间这时候可能会导致窗口线程响应缓慢UI响应卡顿这时候通过多线程设计让多个逻辑事件分配在多个线程中进行操作并处理好多个线程间的同步与交互就能极大的提升程序的用户体验和程序执行效率。 2 使用多线程的一些注意事项
1、Qt中窗口所在的线程为默认主线程窗口的事件处理和控件的数据更新在此线程进行。 2、子线程和主线程之间的数据传递主要通过信号槽机制进行。 3、子线程用于负责非UI部分的后台逻辑不可操作窗口中的对象。 3 QThread类
QThread类是Qt提供的一个不依赖于平台的多线程类。 在使用时通常会定义一个继承QThread类的自定义类重定义虚函数run()的实现用一个从该自定义类实例化的对象来管理一个线程在主线程中通过对象的start()接口来启动线程start()接口底层会调用run()实现在run()实现中调用exit()或者quit()能够结束线程的事件循环在主线程中调用terminate()可以强制结束线程。 但也可以通过从QObject类进行派生的方式来实现多线程这种方式使用起来会更加灵活但是在代码实现上会更复杂一些。 3.1 QThread类的主要接口
QThread类是继承自QObject类的其中主要的一些接口如下 1、[公共函数] 判断线程是否结束bool isFinished() 2、[公共函数] 判断线程是否正在运行bool isRunning() 3、[公共函数] 获得线程的优先级Priority priority() 4、[公共函数] 设置线程的优先级void setPriority(Priority priority) 5、[公共函数] 退出事件循环void exit(int returnCode 0) 6、[公共函数] 阻塞线程执行直到线程结束或者time 毫秒void wait(unsigned long time) 7、[公共槽函数] 退出线程事件循环void quit() 8、[公共槽函数] 根据priority开始调度、执行线程void start(Priority priority) 9、[公共槽函数] 终止线程void terminate() 10、[信号] 在线程快结束完成时发射void finished() 11、[信号] 在线程调用run()实现前发射void started() 12、[静态公共函数] 获得系统可运行的线程的数量int idealThreadCount() 13、[静态公共函数] 强制当前线程休眠msecsint msleep(unsigned long msecs) 14、[静态公共函数] 强制当前线程休眠secsint sleep(unsigned long secs) 15、[静态公共函数] 强制当前线程休眠usecsint usleep(unsigned long usecs) 16、[保护函数] 线程执行体虚函数virtual void run() 17、[保护函数] 进入线程事件循环int exec() 3.2 线程的优先级
在QThread类中声明了从最低到最高的8个优先级(默认情况下为最高优先级QThread::InheritPriority)分别为 QThread::IdelPriority QThread::LowestPriority QThread::LowPriority QThread::NormalPriority QThread::HighPriority QThread::HigestPriority QThread::InheritPriority 4 通过继承QThread类实现多线程
通过自定义一个继承QThread类的自定义类是在Qt开发中最常见的实现多线程的方式。 这种方式的优势在于 1、可以直接重写run()函数实现线程的执行逻辑。 2、可以通过start()函数启动线程比较直观和简单。 但这种方式的劣势也很明显 1、在多线程中直接操作QObject派生类的成员可能会导致线程安全问题需要进行额外的同步处理。 2、QThread类的创建和销毁需要小心处理避免资源泄漏和线程未正常退出的情况。 在具体的操作上通常要经过如下步骤 1、定义一个继承QThread类的自定义类。
class MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent nullptr);
protected:void run() override;
};2、在自定义类中重写父类QThread的run()方法在该实现中编写子线程的具体逻辑、处理、流程。
void MyThread::run()
{// 执行多线程的工作逻辑// ...
}3、在主线程中创建一个子线程对象将自定义的子线程类实例化并连接适当的信号槽来处理工作完成的事件。
MyThread* thread new MyThread(this);
connect(thread, MyThread::finished, this, MainWindow::handleThreadFinished);4、在主线程中通过创建的子线程对象调用start()启动子线程。
thread-start();5、在主线程中和子线程通过信号槽处理线程之间的数据传递、处理逻辑。 6、在合适的时候对线程的资源进行合理的释放 5 从QObject类进行派生实现多线程
通过从QObject类进行派生实现多线程是在Qt开发中另一种使用较多的实现多线程的方式。 这种方式的优势在于 1、QObject类提供了信号槽机制方便多线程之间的通信和数据传递。 2、可以利用Qt的事件循环机制处理事件例如定时器事件、网络事件等。 3、可以使用Qt提供的线程安全的容器和工具类方便进行线程间的数据共享和同步。 但这种方式的劣势在于 1、无法直接重写run()函数需要使用QRunnable接口或QtConcurrent库来实现线程的执行逻辑。 2、对象的生命周期和线程的生命周期紧密相关需要小心处理对象的创建和销毁避免线程结束后对象仍然存在。 在具体的操作上通常要经过如下步骤 1、创建一个QObject类的派生类作为多线程的工作对象
class MyWorker : public QObject
{Q_OBJECT
public:explicit MyWorker(QObject *parent nullptr);
public slots:void doWork();
signals:void workFinished();
};2、在创建的QObject类的派生类中定义一个槽函数 doWork()用于执行多线程的工作逻辑。
void MyWorker::doWork()
{// 执行多线程的工作逻辑// ...// 工作完成后发射信号emit workFinished();
}3、在主线程中创建一个不指定父对象的QThread对象thread并将QObject派生类的对象worker移动到这个线程对象thread中。
QThread* thread new QThread;
MyWorker* worker new MyWorker;
worker-moveToThread(thread);4、连接MyWorker对象的 workFinished() 信号到适当的槽函数以处理工作完成的事件。
QObject::connect(worker, MyWorker::workFinished, this, MainWindow::handleWorkFinished);启动线程并调用 doWork() 函数开始执行多线程工作。
thread-start();
QMetaObject::invokeMethod(worker, doWork);5、通过以上步骤我们就可以从QObject类派生实现多线程并利用信号槽机制进行线程间的通信和数据传递了。 注意在这个例子中我们将MyWorker对象移动到了新创建的线程中并在主线程中通过信号槽机制连接工作完成的信号。这样当 doWork() 函数执行完成后会自动发射 workFinished() 信号触发相应的槽函数执行。 6 小结
整体而言从QObject类派生实现多线程会更加的灵活和功能强大比较适合复杂的多线程应用场景通过信号槽机制和事件循环可以方便地实现线程间的通信和处理。而继承QThread类实现多线程相对简单适用于简单的线程逻辑。在选择时需要根据具体的需求和应用场景来决定使用哪种方式。