使用semaphore进行线程间的同步比使用mutex高级之处就在于其可以同时管理好几个同类资源。
源代码如下:
.h文件
/****************************************************************************
** Form interface generated from reading ui file 'newprojectdialog.ui'
**
** Created: 鏄熸湡鍥?涓夋湀 6 15:05:25 2008
** by: The User Interface Compiler ($Id: qt/main.cpp 3.2.1 edited May 19 14:22 $)
**
** WARNING! All changes made in this file will be lost!
****************************************************************************/#ifndef NEWPROJECTDIALOG_H
#define NEWPROJECTDIALOG_H#include
#include
#include
#include
#includeclass QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QTextEdit;
class QLineEdit;
class QPushButton;class univerData
{
public:
static int in_num;
static int out_num;
static QString str;
//static char buffer[10];
static QSemaphore freeSpace;
static QSemaphore usedSpace;
};class produceThread : public QThread
{
public:
Thread();
void run();
};class consumeThread : public QThread
{
public:
Thread();void run();
};class NewProjectDialog : public QDialog
{
Q_OBJECTpublic:
NewProjectDialog( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
~NewProjectDialog();QTextEdit* textEdit1;
QLineEdit* lineEdit1;
QPushButton* pushButton6;
QPushButton* pushButton7;
QPushButton* pushButton5;
produceThread pp;
consumeThread cc;public slots:
virtual void produce();
virtual void consume();protected:
protected slots:
virtual void languageChange();};
#endif // NEWPROJECTDIALOG_H
.cpp文件如下:
/****************************************************************************
** Form implementation generated from reading ui file 'newprojectdialog.ui'
**
** Created: 鏄熸湡鍥?涓夋湀 6 15:05:27 2008
** by: The User Interface Compiler ($Id: qt/main.cpp 3.2.1 edited May 19 14:22 $)
**
** WARNING! All changes made in this file will be lost!
****************************************************************************/#include "newprojectdialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include/*
* Constructs a NewProjectDialog as a child of 'parent', with the
* name 'name' and widget flags set to 'f'.
*
* The dialog will by default be modeless, unless you set 'modal' to
* TRUE to construct a modal dialog.
*/
QString buffer[10];QSemaphore univerData::freeSpace(10);
QSemaphore univerData::usedSpace(10);
QString univerData::str="hello";
int univerData::in_num=0;
int univerData::out_num=0;
void produceThread::run()
{
int in;
univerData::freeSpace--;
in=univerData::in_num%10;
buffer[in]="hello";
univerData::usedSpace++;
}void consumeThread::run()
{
int out;
univerData::usedSpace--;
out=univerData::out_num%10;univerData::freeSpace++;
}NewProjectDialog::NewProjectDialog( QWidget* parent, const char* name, bool modal, WFlags fl )
: QDialog( parent, name, modal, fl )
{
if ( !name )
setName( "NewProjectDialog" );
setSizeGripEnabled( TRUE );textEdit1 = new QTextEdit( this, "textEdit1" );
textEdit1->setGeometry( QRect( 20, 30, 371, 201 ) );lineEdit1 = new QLineEdit( this, "lineEdit1" );
lineEdit1->setGeometry( QRect( 20, 260, 371, 61 ) );pushButton6 = new QPushButton( this, "pushButton6" );
pushButton6->setGeometry( QRect( 430, 160, 110, 41 ) );pushButton7 = new QPushButton( this, "pushButton7" );
pushButton7->setGeometry( QRect( 430, 270, 111, 41 ) );pushButton5 = new QPushButton( this, "pushButton5" );
pushButton5->setGeometry( QRect( 430, 50, 110, 40 ) );
languageChange();
resize( QSize(585, 363).expandedTo(minimumSizeHint()) );
clearWState( WState_Polished );
// signals and slots connections
connect( pushButton5, SIGNAL( clicked() ), this, SLOT( produce() ) );
connect( pushButton6, SIGNAL( clicked() ), this, SLOT( consume() ) );
connect( pushButton7, SIGNAL( clicked() ), this, SLOT( close() ) );
}/*
* Destroys the object and frees any allocated resources
*/
NewProjectDialog::~NewProjectDialog()
{
// no need to delete child widgets, Qt does it all for us
}/*
* Sets the strings of the subwidgets using the current
* language.
*/
void NewProjectDialog::languageChange()
{
setCaption( tr( "NewProject" ) );
pushButton6->setText( tr( "pushButton6" ) );
pushButton7->setText( tr( "pushButton7" ) );
pushButton5->setText( tr( "pushButton5" ) );
}void NewProjectDialog::produce()
{
pp.start();
}void NewProjectDialog::consume()
{
lineEdit1->setText(buffer[0]);
cc.start();
}此程序主要实现功能如下,生产者向缓冲区中存入数据,消费者从缓冲区中取出数据
需要注意的是在linux下qt不能直接在全局变量区处声明全局变量,但在win下却可以直接在全局变量区处声明全局变量。
还有一点不同的是在linux下可以直接在头文件中定义类中静态变量的值,但如果在win下的qt中直接定义全局变量的值则会提示错误。