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.
tqt3/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 TQt. This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/
#include <ntqapplication.h>
#include <tqwidget.h>
#include <ntqpushbutton.h>
#include <ntqmultilineedit.h>
#include <tqthread.h>
#include <tqsemaphore.h>
#include <tqmutex.h>
#include <ntqlayout.h>
#include <ntqmessagebox.h>
#include <ntqlabel.h>
#if defined(TQT_NO_THREAD)
# error Thread support not enabled.
#endif
// Use pointers to create semaphores after TQApplication object!
TQSemaphore* yellowSem, *greenSem;
class YellowThread : public TQThread
{
public:
YellowThread(TQWidget *o)
: receiver(o), stopped(FALSE)
{ ; }
void run();
void stop();
private:
TQWidget *receiver;
TQMutex mutex;
bool stopped;
};
void YellowThread::run()
{
for (int i = 0; i < 20; i++) {
(*yellowSem)++;
TQCustomEvent *event = new TQCustomEvent(12345);
event->setData(new TQString("Yellow!"));
TQApplication::postEvent(receiver, event);
msleep(200);
(*greenSem)--;
mutex.lock();
if (stopped) {
stopped = FALSE;
mutex.unlock();
break;
}
mutex.unlock();
}
(*yellowSem)++;
TQCustomEvent *event = new TQCustomEvent(12346);
event->setData(new TQString("Yellow!"));
TQApplication::postEvent(receiver, event);
(*greenSem)--;
}
void YellowThread::stop()
{
mutex.lock();
stopped = TRUE;
mutex.unlock();
}
class GreenThread: public TQThread
{
public:
GreenThread(TQWidget *o)
: receiver(o), stopped( FALSE )
{ ; }
void run();
void stop();
private:
TQWidget *receiver;
TQMutex mutex;
bool stopped;
};
void GreenThread::run()
{
for (int i = 0; i < 20; i++) {
(*greenSem)++;
TQCustomEvent *event = new TQCustomEvent(12345);
event->setData(new TQString("Green!"));
TQApplication::postEvent(receiver, event);
msleep(200);
(*yellowSem)--;
mutex.lock();
if (stopped) {
stopped = FALSE;
mutex.unlock();
break;
}
mutex.unlock();
}
(*greenSem)++;
TQCustomEvent *event = new TQCustomEvent(12346);
event->setData(new TQString("Green!"));
TQApplication::postEvent(receiver, event);
msleep(10);
(*yellowSem)--;
}
void GreenThread::stop()
{
mutex.lock();
stopped = TRUE;
mutex.unlock();
}
class SemaphoreExample : public TQWidget
{
TQ_OBJECT
public:
SemaphoreExample();
~SemaphoreExample();
void customEvent(TQCustomEvent *);
public slots:
void startExample();
protected:
private:
TQMultiLineEdit *mlineedit;
TQPushButton *button;
TQLabel *label;
YellowThread yellowThread;
GreenThread greenThread;
};
SemaphoreExample::SemaphoreExample()
: TQWidget(), yellowThread(this), greenThread(this)
{
yellowSem = new TQSemaphore(1);
greenSem = new TQSemaphore(1);
button = new TQPushButton("&Ignition!", this);
connect(button, TQ_SIGNAL(clicked()), TQ_SLOT(startExample()));
mlineedit = new TQMultiLineEdit(this);
label = new TQLabel(this);
TQVBoxLayout *vbox = new TQVBoxLayout(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()) {
TQMessageBox::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(TQCustomEvent *event) {
switch (event->type()) {
case 12345:
{
TQString *s = (TQString *) event->data();
mlineedit->append(*s);
if (*s == "Green!")
label->setBackgroundColor(green);
else
label->setBackgroundColor(yellow);
label->setText(*s);
delete s;
break;
}
case 12346:
{
TQString *s = (TQString *) event->data();
TQMessageBox::information(this, (*s) + " - Finished",
"The thread creating the \"" + *s +
"\" events has finished.");
delete s;
break;
}
default:
{
tqWarning("Unknown custom event type: %d", event->type());
}
}
}
int main(int argc, char **argv)
{
TQApplication app(argc, argv);
SemaphoreExample se;
app.setMainWidget(&se);
se.show();
return app.exec();
}
#include "main.moc"