Qt提供了QThread类以进行多任务处理。与多任务处理一样,Qt提供的线程可以做到单个线程做不到的事情。例如,在网络应用程序中,可以使用线程处理多种连接器。QThread类提供了一个与平台无关的方式来管理线程。首先用一个类继承QThread类,然后重新改写QThread类的虚函数run()。只需要实例该类,然后调用函数start(),就可以开启新的多线程(run()函数被自动调用)。除此之外,还有一种方法,即继承QObject类,然后调用moveToThread()函数开启一个线程槽函数,把要花费大量时间计算的代码放入该线程槽函数中。
我们主要来看第一种方法。注意:只执行了run()函数才是新的线程在执行,所有复杂的逻辑都应该放在run()函数里面。当run()函数运行完毕后,该线程的声明周期就结束了。run()函数的原型声明如下:
[virtual protected] void QThread::run()
我们要做的就是把新线程要执行的操作放到run()函数(线程函数)中。除了run()函数之外,还有其他QThread成员函数有时会用到。
1.QThread类的基本使用
引入头文件#include<QThread>
#include "MainWindow.h"
#include <QApplication>
#include <unistd.h> //for sleep
#include <iostream>
#include <QThread>
using namespace std;
#define handle_error_en(en,msg) do {errno = en;perror(msg);exit(EXIT_FAILURE);}while (0);
#define PTHREAD_NUM 2
class MyThread:public QThread
{
public:
virtual void run();
};
void MyThread::run()
{
for(int count = 0;count<10;count++)
{
sleep(1);
qDebug("ping %d",count);
}
}
int main(int argc, char *argv[])
{
// QApplication a(argc, argv);
// MainWindow w;
// w.show();
MyThread thA;
thA.start();
thA.wait();
cout<<"thread A is over."<<endl;
sleep(5);
pthread_exit(NULL); // the main thread will exit, but main process will not
cout<<"main thread has exited,this line will not run\n"<<endl;
// return a.exec();
}
Output:
ping 0
ping 1
ping 2
ping 3
ping 4
ping 5
ping 6
ping 7
ping 8
ping 9
thread A is over.
2.线程间通信
Qt线程间(数据)通信主要有两种方式:
(1)使用共享内存,也就是使用两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的。
(2)使用信号槽(Signal/Slot>)机制,把数据从一个线程传递到另外一个线程。
第一种方法在各个编程语言中都普遍使用,而第二种方法是QT特有的。这里我们主要介绍第二种方法。我们来看一个例子,子线程发送信号(信号参数是一个整数)给主线程,主线程得到这个信号后显示在便签控件上,子线程每隔一秒就累加一次整数,相当于一个计数器。主线程也可以发送信号给子线程,把计数器重置为0。这一来一往就实现了子线程和主线程的相互通信。示例程序虽小,但是功能与原理和大示例是一样的。
TestThread.h
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <unistd.h> //for sleep
#include <iostream>
#include <QThread>
class TestThread:public QThread
{
Q_OBJECT
public:
TestThread(QObject *parent = 0);
protected:
void run();
signals:
void TestSignal(int);
public slots:
void ResetSlot();
private:
int number;
};
#endif // TESTTHREAD_H
TestThread.cpp
#include "TestThread.h"
TestThread::TestThread(QObject *parent):QThread(parent)
{
number = 0;
}
void TestThread::run()
{
while(1)
{
number++;
emit TestSignal(number);
sleep(1);
}
}
void TestThread::ResetSlot()
{
number = 0;
emit TestSignal(number);
}
//线程开始:
TestThread* thA = new TestThread();
//connetc() //绑定好相关的信号连接
//connect() //
thA->start(); //
首先从QThread类继承了一个自定义类MyThread,并实现了run()函数。然后在main()主函数中创建MyThread类的对象thA,并调用QThread类的start()函数,该函数将会启动子线程,即run()函数会执行。
网友评论