10 void startOrStopThreadB;

11 private:

12 Thread threadA;

13 Thread threadB;

14 QPushButton *threadAButton;

15 QPushButton *threadBButton;

16 QPushButton *quitButton;

17 };

В классе ThreadDialog объявляются две переменные типа Thread и несколько кнопок для обеспечения основных средств интерфейса пользователя.

01 ThreadDialog::ThreadDialog(QWidget *parent)

02 : QDialog(parent)

03 {

04 threadA.setMessage("А");

05 threadB.setMessage("B");

06 threadAButton = new QPushButton(tr("Start А"));

07 threadBButton = new QPushButton(tr("Start В"));

08 quitButton = new QPushButton(tr("Quit"));

09 quitButton->setDefault(true);

10 connect(threadAButton, SIGNAL(clicked),

11 this, SLOT(startOrStopThreadA));

12 connect(threadBButton, SIGNAL(clicked),

13 this, SLOT(startOrStopThreadB));

14 …

15 }

В конструкторе мы вызываем функцию setMessage для периодического вывода на экран первым потоком буквы «А» и вторым потоком буквы «В».

01 void ThreadDialog::startOrStopThreadA

02 {

03 if (threadA.isRunning) {

04 threadA.stop;

05 threadAButton->setText(tr("Start А"));

06 } else {

07 threadA.start;

08 threadAButton->setText(tr("Stop А"));

09 }

10 }

Когда пользователь нажимает кнопку потока А, функция startOrStopThreadA останавливает поток, если он выполняется, и запускает его в противном случае. Она также обновляет текст кнопки.

01 void ThreadDialog::startOrStopThreadB

02 {

03 if (threadB.isRunning) {

04 threadB.stop;

05 threadBButton->setText(tr("Start В"));

06 } else {

07 threadB.start;

08 threadBButton->setText(tr("Stop В"));

09 }

10 }

Программный код функции startOrStopThreadB очень похож.

01 void ThreadDialog::closeEvent(QCloseEvent *event)

02 {

03 threadA.stop;

04 threadB.stop;

05 threadA.wait;

06 threadB.wait;

07 event->accept;

08 }

Если пользователь выбирает пункт меню Quit или закрывает окно, мы даем команду останова для каждого выполняющегося потока и ожидаем их завершения (используя функцию QThread::wait) прежде, чем сделать вызов CloseEvent::accept. Это обеспечивает аккуратный выход из приложения, хотя в данном случае это не имеет значения.

Если при выполнении приложения вы нажмете кнопку Start А, консоль заполнится буквами «А». Если вы нажмете кнопку Start В, консоль заполнится попеременно последовательностями букв «А» и «В». Нажмите кнопку Stop А, и тогда на экран будет выводиться только последовательность букв «В».

<p>Синхронизация потоков</p>

Обычным требованием для многопоточных приложений является синхронизация работы нескольких потоков. Для этого в Qt предусмотрены следующие классы: QMutex, QReadWriteLock, QSemaphore и QWaitCondition.

Класс QMutex обеспечивает такую защиту переменной или участка программного кода, что доступ к ним в каждый момент времени может осуществлять только один поток. Этот класс содержит функцию lock, которая закрывает мьютекс (mutex). Если мьютекс открыт, текущий поток захватывает его и немедленно закрывает; в противном случае работа текущего потока блокируется до тех пор, пока захвативший мьютекс поток не освободит его. В любом случае после вызова lock текущий поток будет держать мьютекс до вызова им функции unlock. Класс QMutex содержит также функцию tryLock, которая сразу же возвращает управление, если мьютекс уже закрыт.

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже