You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qt3/examples/thread/semaphores/main.cpp

275 lines
4.9 KiB

/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
**
** This file is part of an example program for Qt. This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/
#include <qapplication.h>
#include <qwidget.h>
#include <qpushbutton.h>
#include <qmultilineedit.h>
#include <qthread.h>
#include <qsemaphore.h>
#include <qmutex.h>
#include <qlayout.h>
#include <qmessagebox.h>
#include <qlabel.h>
#if defined(QT_NO_THREAD)
# error Thread support not enabled.
#endif
// Use pointers to create semaphores after QApplication object!
QSemaphore* yellowSem, *greenSem;
class YellowThread : public QThread
{
public:
YellowThread(QWidget *o)
: receiver(o), stopped(FALSE)
{ ; }
void run();
void stop();
private:
QWidget *receiver;
QMutex mutex;
bool stopped;
};
void YellowThread::run()
{
for (int i = 0; i < 20; i++) {
(*yellowSem)++;
QCustomEvent *event = new QCustomEvent(12345);
event->setData(new QString("Yellow!"));
QApplication::postEvent(receiver, event);
msleep(200);
(*greenSem)--;
mutex.lock();
if (stopped) {
stopped = FALSE;
mutex.unlock();
break;
}
mutex.unlock();
}
(*yellowSem)++;
QCustomEvent *event = new QCustomEvent(12346);
event->setData(new QString("Yellow!"));
QApplication::postEvent(receiver, event);
(*greenSem)--;
}
void YellowThread::stop()
{
mutex.lock();
stopped = TRUE;
mutex.unlock();
}
class GreenThread: public QThread
{
public:
GreenThread(QWidget *o)
: receiver(o), stopped( FALSE )
{ ; }
void run();
void stop();
private:
QWidget *receiver;
QMutex mutex;
bool stopped;
};
void GreenThread::run()
{
for (int i = 0; i < 20; i++) {
(*greenSem)++;
QCustomEvent *event = new QCustomEvent(12345);
event->setData(new QString("Green!"));
QApplication::postEvent(receiver, event);
msleep(200);
(*yellowSem)--;
mutex.lock();
if (stopped) {
stopped = FALSE;
mutex.unlock();
break;
}
mutex.unlock();
}
(*greenSem)++;
QCustomEvent *event = new QCustomEvent(12346);
event->setData(new QString("Green!"));
QApplication::postEvent(receiver, event);
msleep(10);
(*yellowSem)--;
}
void GreenThread::stop()
{
mutex.lock();
stopped = TRUE;
mutex.unlock();
}
class SemaphoreExample : public QWidget
{
Q_OBJECT
public:
SemaphoreExample();
~SemaphoreExample();
void customEvent(QCustomEvent *);
public slots:
void startExample();
protected:
private:
QMultiLineEdit *mlineedit;
QPushButton *button;
QLabel *label;
YellowThread yellowThread;
GreenThread greenThread;
};
SemaphoreExample::SemaphoreExample()
: QWidget(), yellowThread(this), greenThread(this)
{
yellowSem = new QSemaphore(1);
greenSem = new QSemaphore(1);
button = new QPushButton("&Ignition!", this);
connect(button, SIGNAL(clicked()), SLOT(startExample()));
mlineedit = new QMultiLineEdit(this);
label = new QLabel(this);
QVBoxLayout *vbox = new QVBoxLayout(this, 5);
vbox->addWidget(button);
vbox->addWidget(mlineedit);
vbox->addWidget(label);
}
SemaphoreExample::~SemaphoreExample()
{
bool stopYellow = yellowThread.running(),
stopGreen = greenThread.running();
if (stopYellow)
yellowThread.stop();
if (greenThread.running())
greenThread.stop();
if (stopYellow)
yellowThread.wait();
if (stopGreen)
greenThread.wait();
delete yellowSem;
delete greenSem;
}
void SemaphoreExample::startExample()
{
if (yellowThread.running() || greenThread.running()) {
QMessageBox::information(this, "Sorry",
"The threads have not completed yet, and must finish before "
"they can be started again.");
return;
}
mlineedit->clear();
while (yellowSem->available() < yellowSem->total()) (*yellowSem)--;
(*yellowSem)++;
yellowThread.start();
greenThread.start();
}
void SemaphoreExample::customEvent(QCustomEvent *event) {
switch (event->type()) {
case 12345:
{
QString *s = (QString *) event->data();
mlineedit->append(*s);
if (*s == "Green!")
label->setBackgroundColor(green);
else
label->setBackgroundColor(yellow);
label->setText(*s);
delete s;
break;
}
case 12346:
{
QString *s = (QString *) event->data();
QMessageBox::information(this, (*s) + " - Finished",
"The thread creating the \"" + *s +
"\" events has finished.");
delete s;
break;
}
default:
{
qWarning("Unknown custom event type: %d", event->type());
}
}
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
SemaphoreExample se;
app.setMainWidget(&se);
se.show();
return app.exec();
}
#include "main.moc"