QT为多线程编程提供了很多类,其中最重要的就是QThread了,在QT中定义的任何线程都是他的派生类。最重要的就是重写run()函数,因为类的主要功能就是在run中实现,实现的方法是调用start函数,start函数就会自动调用run函数。
以下程序是一个简单的多线程程序,主要功能是生成两个线程,每个线程不停的打印自己的相关信息。
代码如下:
form1.h
/****************************************************************************
** Form interface generated from reading ui file 'form1.ui'
**
** Created: 日 2月 10 14:45:53 2008
** by: The User Interface Compiler ($Id: qt/main.cpp 3.1.1 edited Nov 21 17:40 $)
**
** WARNING! All changes made in this file will be lost!
****************************************************************************/
#ifndef FORM1_H
#define FORM1_H
#include <qvariant.h>
#include <qwidget.h>
#include <qthread.h>
#include <qmutex.h>
#include <iostream.h>
class QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QPushButton;
class MutthreadA : public QThread
{
//QT_THREAD_SUPPORT
public:
void run()
{
while(1)
{
cout << "THE THREAD AZD IS RUN/n";
sleep(2);
}
};
};
class MutthreadB:public QThread
{
public:
void run()
{
while(1)
{
cout << "THE THREAD B IS RUN/n";
sleep(2);
}
};
};
class Form1 : public QWidget
{
Q_OBJECT
public:
Form1( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
~Form1();
QPushButton* pushButton1;
QPushButton* pushButton2;
MutthreadA AA;
MutthreadB BB;
QMutex mutex;
protected:
protected slots:
virtual void languageChange();
virtual void Ta();
virtual void Tb();
};
#endif // FORM1_H
form1.cpp
/****************************************************************************
** Form implementation generated from reading ui file 'form1.ui'
**
** Created: 日 2月 10 14:46:03 2008
** by: The User Interface Compiler ($Id: qt/main.cpp 3.1.1 edited Nov 21 17:40 $)
**
** WARNING! All changes made in this file will be lost!
****************************************************************************/
#include "form1.h"
#include <qvariant.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qmutex.h>
/*
* Constructs a Form1 as a child of 'parent', with the
* name 'name' and widget flags set to 'f'.
*/
Form1::Form1( QWidget* parent, const char* name, WFlags fl )
: QWidget( parent, name, fl )
{
if ( !name )
setName( "Form1" );
pushButton1 = new QPushButton( this, "pushButton1" );
pushButton1->setGeometry( QRect( 50, 80, 161, 61 ) );
pushButton2 = new QPushButton( this, "pushButton2" );
pushButton2->setGeometry( QRect( 50, 200, 161, 61 ) );
languageChange();
resize( QSize(600, 480).expandedTo(minimumSizeHint()) );
connect(pushButton1,SIGNAL(clicked()),this,SLOT(Ta()));
connect(pushButton2,SIGNAL(clicked()),this,SLOT(Tb()));
}
/*
* Destroys the object and frees any allocated resources
*/
Form1::~Form1()
{
// no need to delete child widgets, Qt does it all for us
}
/*
* Sets the strings of the subwidgets using the current
* language.
*/
void Form1::languageChange()
{
setCaption( tr( "Form1" ) );
pushButton1->setText( tr( "printerA" ) );
pushButton2->setText( tr( "printerB" ) );
}
void Form1::Ta()
{
if(AA.running())
{
AA.wait();
mutex.unlock();
}
else
{
mutex.lock();
//AA.run();
AA.start();
}
}
void Form1::Tb()
{
if(BB.running())
{
BB.wait();
mutex.unlock();
}
else
{
mutex.lock();
// BB.run();
BB.start();
}
}
main.cpp
#include <qapplication.h>
#include "form1.h"
int main( int argc, char ** argv )
{
QApplication a( argc, argv );
Form1 w;
w.show();
a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
return a.exec();
}
程序中用了互斥量mutex,其实现了两个线程间的通信。还需要注意的是当调用线程的start函数时,run函数会自动被调用。但是需要注意的是也可以直接调用run函数来实现线程的相关功能,但是这样将不会出现多线程,系统还是执行的单线程,即使先执行AA线程,AA线程执行完了后才执行BB线程。
程序执行结果如下:
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
THE THREAD AZD IS RUN
THE THREAD B IS RUN
.
.
.
.
.
还需要注意的一点是在编译的时候必须在makefile中加入-DQT_THREAD_SUPPORT即:
CFLAGS = -pipe -Wall -W -O2 -march=i386 -mcpu=i686 -g -DGLX_GLXEXT_LEGACY -fno-use-cxa-atexit -fno-exceptions -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
CXXFLAGS = -pipe -Wall -W -O2 -march=i386 -mcpu=i686 -g -DGLX_GLXEXT_LEGACY -fno-use-cxa-atexit -fno-exceptions -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
以实现对多线程的支持。(前提是QT在编译的时候已经加入了多线程选项,即生成了多线程库)