Qt之多线程编程初识

做项目时遭遇用户界面冻结的问题,究其原因是槽函数里装了一个需要CPU密集操作的功能。使用多线程,可以解决界面冻结的问题。

多线程的几大特点:

  1. 多线程的执行顺序无法保证,与操作系统的调度策略和线程优先级等因素有关。
  2. 多线程的切换可能发生在任何时刻、任何地点。
  3. 多线程对代码的敏感度高,因此对代码的细微修改都可能产生意想不到的效果。

先由一个简单的例子引出多线程

先作出这个简单的界面

“开始”对应的槽函数是:slotStart()

“停止”对应的槽函数是:slotStop()

本例中的线程(workthread类)实现的功能是,从0到9循环打印,0至9各占一排。

则该线程的具体实现如下:

#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread();

protected:
    void run();

};

#endif // WORKTHREAD_H
#include "workthread.h"

#include <QtDebug>

WorkThread::WorkThread()
{

}

void WorkThread::run()
{
     while(true)

  {
      for(int n=0;n<10;n++)
      qDebug()<<n<<n<<n<<n<<n<<n<<n<<n;
  }

}

好了,现在该在本窗口对象的头文件里添加这个线程属性

private:
WorkThread *workThread[MAXSIZE];
MAXSIZE表示最大生成的线程数,可以根据个人喜好自行选择,只要你的CPU带得动。当然,这里为了展示多线程的特性,我们分别将MAXSIZE置为1及5。

完善之前两个槽函数的功能。

void CH1201::slotStart()
{
   qDebug() << "slotStart";
   for (int i = 0; i < MAXSIZE; i++)
   {
      workThread[i] = new WorkThread();
   }
   for (int i = 0; i < MAXSIZE; i++)
   {
      workThread[i]->start();
   }
   ui.startBtn->setEnabled(false);
   ui.stopBtn->setEnabled(true);
}
void CH1201::slotStop()
{
   for (int i = 0; i < MAXSIZE; i++)
   {
      workThread[i]->terminate();
      workThread[i]->wait();
   }
   ui.startBtn->setEnabled(true);
   ui.stopBtn->setEnabled(false);
}

线程类方法顾名思义大致都能看懂。现在多说两句我自己没怎么接触的:

terminate() 依次终止保存在workThread[]数组中的WorkThread类实例。但是terminate()函数并不会立刻终止这个线程,该线程何时终止取决于操作系统的调度策略。

wait() 使得线程阻塞等待直到退出或超时。
下面观赏一下qDebug()的结果:

下图是MAXSIZE为5是的打印结果,可以看出输出结果是乱序的,我们根本无法猜测操作系统到底是怎么调度这五个线程的。

下图是MAXSIZE为1的打印结果,输出数字顺序有规律,显然只有一个线程在工作。

PS:IDE用的VS2015,我刚开始不知道qDebug打印的调试信息显示在哪里,查了一会儿才知道,qDebug打印的调试信息显示在console。至于调出console的方法也很简单,点击VS左上菜单之一“项目”,选择最下方的“属性”,点击“链接器”,点击“链接器”树下的“系统”,目光移到弹出窗口的中央,更改”子系统“为:”控制台/SUBSYSTEM:CONSOLE“。

猜你喜欢

转载自blog.csdn.net/Aidam_Bo/article/details/81743684
今日推荐