最近做了些QT的项目,感触很深,写几篇博客,记录下来最近一段时间接触QT的一些相关内容。
先简单介绍一下项目的基本功能,项目的基本功能是实时收发来自局域网的tcp消息,并处理完成数据。实时处理数据,这个问题有一个关键的一点是,数据接收的速度和处理的速度不匹配的时候,需要对接收到的数据进行暂时的缓存,这个按照程序的自上而下的顺序执行过程,肯定是不能满足要求的,所以,多线程的作用就体现出来了,多线程可以相互辅助工作,摆脱原有的一个进程只能自上而下执行的限制,更好的完成工作。
下面简单介绍一下qt的线程:
QT的线程,在实现自己的线程操作的时候,继承使用QThread这个类即可,下面我提供一个自己写的关于线程的Demo方便大家参考;
MyThread.h
#ifndef MYTHREADTASK_H
#define MYTHREADTASK_H
#include <QThread>
#include <QDebug>
class CMyThreadTask: public QThread
{
public:
CMyThreadTask();
~CMyThreadTask(){}
void run(); ///< 启动任务
void init(); ///< 初始化任务
void TaskStop(); ///< 任务停止
private:
bool stopped;
};
#endif // MYTHREADTASK_H
MyThread.cpp
#include "mythreadtask.h"
CMyThreadTask::CMyThreadTask()
{
stopped = false;
}
void CMyThreadTask::init()
{
/**
* @brief start
* 调用run()函数
*/
stopped = false;
start(); /// 自动调用run()函数(具体可以查看这个函数的定义)
}
void CMyThreadTask::run()
{
while(!stopped) {
/**
* 执行线程的任务
*/
qDebug()<<"I am run";
}
qDebug()<<"I have been stopped";
}
void CMyThreadTask::TaskStop()
{
stopped = true;
}
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mythreadtask.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_clicked();
void on_pushButton_stop_clicked();
private:
Ui::Widget *ui;
CMyThreadTask *threadtask; ///< 任务类的对象
};
#endif // WIDGET_H
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
threadtask = new CMyThreadTask();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
threadtask->init(); /// 初始化任务
}
void Widget::on_pushButton_stop_clicked()
{
threadtask->TaskStop(); /// 停止任务
}
上面这个是一个简单的界面,start按钮开始任务,stop按钮停止任务。
在QThread这个类中,start()函数,会自行调用run()函数,这个函数的定义void QThread::start(Priority priority = InheritPriority);从参数中可以看出,给了默认参数,也是该线程的优先级的定义。该函数在执行的过程中会自动调用run()函数。操作系统也将给按照给出的优先级在操作系统中执行。
在使用MyThreadTask这个类时,通过调用start()函数,来开启线程。这个时候有一个问题,不知大家注意没有,就是run()函数中,while(!stopped);这个循环,对于stopped这个变量来说,初始化在init()和构造函数中,这个任务从调用run()函数,会直接进入这个while循环,在循环内如果没有改变stopped这个变量的值,那么这个循环会一直执行,这也是保证在某种需要线程始终运行,并且不退出的条件下执行的保证,在某种程度上,相当于while(1)。
这个时候需要注意一些问题,对于某些机器来说,例如单核、双核、四核,这个循环会占用一个cpu,导致程序运行的时候,CPU占用率过高。对于这种多线程的任务,需要考虑到,在任务执行的时候,不要总是占着cpu资源不放,分析清楚任务的功能模块,适当的使用sleep()函数,暂时释放cpu资源,从而让机器能够有效的处理多线程任务。