Qt技巧:多线程实现方法

(转载自: http://blog.youkuaiyun.com/u011314012/article/details/49993659
 
通常情况下,应用程序都是在一个线程中执行操作。但是,当调用一个耗时操作(例如,大批量I/O或大量矩阵变换等CPU密集操作)时,用户界面常常会冻结。而使用
多线程可解决这一问题。
多线程具有以下几点优势。
(1)提高应用程序的响应速度。这对于开发图形界面的程序尤为重要,当一个操作耗时很长时,整个系统都会等待这个操作,程序就不能响应键盘、鼠标、菜单等的操
作,而是使用了多线程技术可将耗时长的操作置于一个新的线程,从而避免以上的问题。
(2)使多CPU系统更加有效。当线程数不大于CPU数目时,操作系统可以调度不同的线程运行于不同的CPU上。
(3)改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为独立或半独立的运行部分,这样有利于代码的理解和维护。
多线程程序有以下几个特点。
(1)多线程程序的行为无法预期,当多次执行上述程序时,每一次的运行结构都可能不同。
(2)多线程的执行顺序无法保证,它与操作系统的调度策略和线程优先级等因素有关。
(3)多线程的切换可能发生在任何时刻、任何地点。
(4)多线程对代码的敏感度高,因此对代码的细微修改都可能产生意想不到的结果。
基于以上这些特点,为了有效地使用线程,开发人员必须对其进行控制。
12.1 多线程及简单实例
点击“开始”按钮将启动数个工作线程(工作线程数目由MAXSIZE宏决定),各个线程循环打印数字0-9.直到按下“停止”按钮终止所有线程为止。
运行效果:
 
threaddlg.h
 
#ifndef THREADDLG_H
#define THREADDLG_H
 
 
#include <QDialog>
#include <QPushButton>
#include "workthread.h"
 
 
#define MAXSIZE 5
 
 
class ThreadDlg : public QDialog
{
  
  
    Q_OBJECT
 
 
public:
    ThreadDlg(QWidget *parent = 0);
    ~ThreadDlg();
private:
    QPushButton *startBtn;
    QPushButton *stopBtn;
    QPushButton *exitBtn;
public slots:
    void slotstart();                   //启动线程槽函数
    void slotstop();                    //终止线程槽函数
private:
    WorkThread *workThread[MAXSIZE];    //指向工作线程的私有指针数组,记录了所启动的全部线程
};
 
 
#endif // THREADDLG_H
 
threaddlg.cpp
 
#include "threaddlg.h"
#include <QHBoxLayout>
 
 
ThreadDlg::ThreadDlg(QWidget *parent)
    : QDialog(parent)
{
  
  
    setWindowTitle(tr("线程"));
    startBtn = new QPushButton(tr("开始"));
    stopBtn = new QPushButton(tr("停止"));
    exitBtn = new QPushButton(tr("退出"));
 
 
    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    mainLayout->addWidget (startBtn);
    mainLayout->addWidget (stopBtn);
    mainLayout->addWidget (exitBtn);
 
 
    startBtn->setEnabled (true);
    stopBtn->setEnabled (true);
 
 
    connect (startBtn, SIGNAL(clicked(bool)), this, SLOT(slotstart()));
    connect (stopBtn, SIGNAL(clicked(bool)), this, SLOT(slotstop()));
    connect (exitBtn, SIGNAL(clicked(bool)), this, SLOT(close()));
}
 
 
ThreadDlg::~ThreadDlg()
{
  
  
 
 
}
/*
 * 这里使用两个循环,目的是为了使新建的线程尽可能开始执行
*/
void ThreadDlg::slotstart ()
{
  
  
    for(int i = 0; i < MAXSIZE; i++)
    {
  
  
        workThread[i] = new WorkThread();
    }
    for(int i = 0; i < MAXSIZE; i++)
    {
  
  
        workThread[i]->start ();
    }
    startBtn->setEnabled (false);
    stopBtn->setEnabled (true);
}
/*
 * workThread[i]->terminate ()、 workThread[i]->wait ():调用QThread基类的terminate()函数,依次终止保存在
 * workThread[]数组中的WorkThread类实例。但是terminate()函数并不会立刻终止这个线程,该线程何时终止取决于操作系统的
 * 调度策略。因此,程序紧挨着调用了QThread基类的wait()函数,它使得线程阻塞等待直到退出或超时。
*/
void ThreadDlg::slotstop ()
{
  
  
   if(!startBtn->isEnabled())
   {
  
  
       for(int i = 0; i < MAXSIZE; i++)
       {
  
  
            workThread[i]->terminate ();
            workThread[i]->wait ();
       }
       startBtn->setEnabled (true);
       stopBtn->setEnabled (false);
   }
}
 
workthread.h
 
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
 
 
#include <QThread>
 
 
class WorkThread : public QThread
{
  
  
public:
    WorkThread();
protected:
    void run();
};
 
 
#endif // WORKTHREAD_H
 
workthread.cpp
 
#include "workthread.h"
#include <QDebug>
 
 
WorkThread::WorkThread()
{
  
  
 
 
}
 
 
void WorkThread::run ()
{
  
  
    while(true)
    {
  
  
        for(int 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值