初出茅庐之Qt,多线程中的线程池QThreadPool和QRunnable

初出茅庐之Qt,多线程中的线程池QThreadPool和QRunnable

 

通常情况下,应用程序都是在一个线程中直行操作。但是,当调用一个耗时操作(例如,大批量IO数据或者大量矩阵变换等CPU密集操作)时,用户界面常常会冻结。而使用多线程就可以解决这一问题。

多线程具有以下几点优势:

1,提高应用程序的响应速度,这对于开发图形界面的程序尤为重要,当一个操作耗时很长是,整个系统都会等待这个操作,程序就不能及时响应键盘、鼠标、菜单等的操作,而使用多线程技术可以将耗时长的操作置于一个新的线程,从而避免以上问题;

2,使多核CPU系统更加有效。当线程数不大于CPU数目时,操作系统可以调度不同的线程运行与不同的CPU上;

3,改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为独立或者半独立的运行部分,这样有利于代码的理解和维护;

多线程程序有一下几个特点:

1,多线程程序的行为无法预期,当多次执行上述程序时,每一次的运行结果都可能不同;

2,多线程的执行顺序无法保证,它与操作系统的调度策略和线程优先级等因素有关;

3,多线程的切换可能发生在任何时刻、任何地点;

4,多线程对代码的敏感度高,因此对代码的细微修改都可能产生意想不到的结果。

因此基于以上的特点,为了有效的使用多线程,开发人员必须对其进行控制;

本次主要就根据项目中实际使用的QThreadPool和QRunnable进行简单介绍,大神勿喷;

 

Qt封装的线程池类是QThreadPool,它的使用需要QRunnable来配合。概括一下使用步骤如下:

    1.从QRunnable派生一个类,重写run()函数。把需要子线程干的活放到run函数中。

    2.调用QThreadPool的start()开始工作,start的参数就是子类化QRunnable的指针。

使用步骤很简单,例如:

QThreadPool pool_;
pool_.setMaxThreadCount(4);
pool_.start(new Task(high_buffer,low_buffer,height,width,time,this));
//此处的Task为基于public QRunnable创建的类,其中


class Task:public QObject,public QRunnable{
    Q_OBJECT
    friend class DataAnalyzer;
public:
    Task(unsigned short* high_buffer,unsigned short* low_buffer,int height,int width,QTime collect_finish_time,DataAnalyzer* data_analyzer);

    void run(){        
        analyze(high_buffer_,low_buffer_,height_,width_,time_);
    }
    void analyze(unsigned short* high_buffer,unsigned short* low_buffer,int height,int width,QTime time);
    ~Task();
private:
    unsigned short* high_buffer_;
    unsigned short* low_buffer_;
    int height_;
    int width_;
    QTime time_;
};

所以执行为pool_.start()后就把所有的任务扔给了Task即可,具体实现由Task::run()实现。

可以看到新建的任务在子线程中执行了;

 线程池在执行完任务后会自动删除任务对象(在start中new出来的CTask),除非你使用setAutoDelete(false)。 QRunnable除了run也就这点本事了。

最后提一点就是Qt为每个QApplication创建了一个线程池对象,通过QThreadPool的静态成员函数globalInstance()可以获得这个对象。不用怀疑拿起来用就是了,出了问题别找我就行了。

你可能感兴趣的:(Qt)