source: trunk/examples/thread/semaphores/main.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1/****************************************************************************
2** $Id: main.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
5**
6** This file is part of an example program for Qt. This example
7** program may be used, distributed and modified without limitation.
8**
9*****************************************************************************/
10#include <qapplication.h>
11#include <qwidget.h>
12#include <qpushbutton.h>
13#include <qmultilineedit.h>
14#include <qthread.h>
15#include <qsemaphore.h>
16#include <qmutex.h>
17#include <qlayout.h>
18#include <qmessagebox.h>
19#include <qlabel.h>
20
21#if defined(QT_NO_THREAD)
22# error Thread support not enabled.
23#endif
24
25// Use pointers to create semaphores after QApplication object!
26QSemaphore* yellowSem, *greenSem;
27
28
29class YellowThread : public QThread
30{
31public:
32 YellowThread(QWidget *o)
33 : receiver(o), stopped(FALSE)
34 { ; }
35
36 void run();
37 void stop();
38
39
40private:
41 QWidget *receiver;
42 QMutex mutex;
43 bool stopped;
44};
45
46
47void YellowThread::run()
48{
49 for (int i = 0; i < 20; i++) {
50 (*yellowSem)++;
51
52 QCustomEvent *event = new QCustomEvent(12345);
53 event->setData(new QString("Yellow!"));
54 QApplication::postEvent(receiver, event);
55 msleep(200);
56
57 (*greenSem)--;
58
59 mutex.lock();
60 if (stopped) {
61 stopped = FALSE;
62 mutex.unlock();
63 break;
64 }
65 mutex.unlock();
66 }
67
68 (*yellowSem)++;
69
70 QCustomEvent *event = new QCustomEvent(12346);
71 event->setData(new QString("Yellow!"));
72 QApplication::postEvent(receiver, event);
73
74 (*greenSem)--;
75}
76
77void YellowThread::stop()
78{
79 mutex.lock();
80 stopped = TRUE;
81 mutex.unlock();
82}
83
84
85class GreenThread: public QThread
86{
87public:
88 GreenThread(QWidget *o)
89 : receiver(o), stopped( FALSE )
90 { ; }
91
92 void run();
93 void stop();
94
95
96private:
97 QWidget *receiver;
98 QMutex mutex;
99 bool stopped;
100};
101
102
103void GreenThread::run()
104{
105 for (int i = 0; i < 20; i++) {
106 (*greenSem)++;
107
108 QCustomEvent *event = new QCustomEvent(12345);
109 event->setData(new QString("Green!"));
110 QApplication::postEvent(receiver, event);
111 msleep(200);
112
113 (*yellowSem)--;
114
115 mutex.lock();
116 if (stopped) {
117 stopped = FALSE;
118 mutex.unlock();
119 break;
120 }
121 mutex.unlock();
122 }
123
124 (*greenSem)++;
125
126 QCustomEvent *event = new QCustomEvent(12346);
127 event->setData(new QString("Green!"));
128 QApplication::postEvent(receiver, event);
129 msleep(10);
130
131 (*yellowSem)--;
132}
133
134void GreenThread::stop()
135{
136 mutex.lock();
137 stopped = TRUE;
138 mutex.unlock();
139}
140
141
142
143class SemaphoreExample : public QWidget
144{
145 Q_OBJECT
146public:
147 SemaphoreExample();
148 ~SemaphoreExample();
149
150 void customEvent(QCustomEvent *);
151
152
153public slots:
154 void startExample();
155
156
157protected:
158
159
160private:
161 QMultiLineEdit *mlineedit;
162 QPushButton *button;
163 QLabel *label;
164
165 YellowThread yellowThread;
166 GreenThread greenThread;
167};
168
169
170SemaphoreExample::SemaphoreExample()
171 : QWidget(), yellowThread(this), greenThread(this)
172{
173 yellowSem = new QSemaphore(1);
174 greenSem = new QSemaphore(1);
175
176 button = new QPushButton("&Ignition!", this);
177 connect(button, SIGNAL(clicked()), SLOT(startExample()));
178
179 mlineedit = new QMultiLineEdit(this);
180 label = new QLabel(this);
181
182 QVBoxLayout *vbox = new QVBoxLayout(this, 5);
183 vbox->addWidget(button);
184 vbox->addWidget(mlineedit);
185 vbox->addWidget(label);
186}
187
188
189SemaphoreExample::~SemaphoreExample()
190{
191 bool stopYellow = yellowThread.running(),
192 stopGreen = greenThread.running();
193 if (stopYellow)
194 yellowThread.stop();
195 if (greenThread.running())
196 greenThread.stop();
197 if (stopYellow)
198 yellowThread.wait();
199 if (stopGreen)
200 greenThread.wait();
201 delete yellowSem;
202 delete greenSem;
203}
204
205
206void SemaphoreExample::startExample()
207{
208 if (yellowThread.running() || greenThread.running()) {
209 QMessageBox::information(this, "Sorry",
210 "The threads have not completed yet, and must finish before "
211 "they can be started again.");
212
213 return;
214 }
215
216 mlineedit->clear();
217
218 while (yellowSem->available() < yellowSem->total()) (*yellowSem)--;
219 (*yellowSem)++;
220
221 yellowThread.start();
222 greenThread.start();
223}
224
225
226void SemaphoreExample::customEvent(QCustomEvent *event) {
227 switch (event->type()) {
228 case 12345:
229 {
230 QString *s = (QString *) event->data();
231
232 mlineedit->append(*s);
233
234 if (*s == "Green!")
235 label->setBackgroundColor(green);
236 else
237 label->setBackgroundColor(yellow);
238 label->setText(*s);
239
240 delete s;
241
242 break;
243 }
244
245 case 12346:
246 {
247 QString *s = (QString *) event->data();
248
249 QMessageBox::information(this, (*s) + " - Finished",
250 "The thread creating the \"" + *s +
251 "\" events has finished.");
252 delete s;
253
254 break;
255 }
256
257 default:
258 {
259 qWarning("Unknown custom event type: %d", event->type());
260 }
261 }
262}
263
264
265int main(int argc, char **argv)
266{
267 QApplication app(argc, argv);
268 SemaphoreExample se;
269 app.setMainWidget(&se);
270 se.show();
271 return app.exec();
272}
273
274
275#include "main.moc"
Note: See TracBrowser for help on using the repository browser.