Синхронизация потоков
Обычным требованием для многопоточных приложений является синхронизация работы нескольких потоков. Для этого в Qt предусмотрены следующие классы: QMutex, QReadWriteLock, QSemaphore и QWaitCondition.
Класс QMutex обеспечивает такую защиту переменной или участка программного кода, что доступ к ним в каждый момент времени может осуществлять только один поток. Этот класс содержит функцию 1оск(), которая закрывает мьютекс (mutex). Если мьютекс открыт, текущий поток захватывает его и немедленно закрывает; в противном случае работа текущего потока блокируется до тех пор, пока захвативший мьютекс поток не освободит его. В любом случае после вызова 1оск() текущий поток будет держать мьютекс до вызова им функции unlock(). Класс QMutex содержит также функцию t ryl_ock(), которая сразу же возвращает управление, если мьютекс уже закрыт.
Предположим, что нам нужно обеспечить защиту переменной stopped класса Thread из предыдущего раздела с помощью QMutex. Тогда мы бы добавили к классу Thread следующую переменную-член:
private:
QMutex mutex;
};
Функция run() изменилась бы следующим образом:
void Thread::run() {
forever {
mutex.lock(); if (stopped) {
stopped = false;
mutex.unlock();
break;
}
mutex.unlock();
cerr « qPrintable(messageStr.ascii); }
cerr « endl; }
Функция stop() стала бы такой:
void Thread::stop() {
mutex.lock(); stopped = true; mutex.unlock();
}
Блокировка и разблокировка мьютекса в сложных функциях или там, где обрабатываются исключения С++, может иметь ошибки. Qt предлагает удобный класс QMutexLocker, упрощающий обработку мьютексов. Конструктор QMutexLocker принимает в качестве аргумента объект QMutex и блокирует его. Деструктор QMutexLocke г разблокирует мьютекс. Например, мы могли бы приведенные выше функции гип() и stop() переписать следующим образом:
void Thread::run() {
forever { {
QMutexLocker locker(&mutex); if (stopped) {
stopped = false;
break;
}
}
cerr « qPrintable(messageStr);
}
cerr « endl;
}
void Thread::stop() {
QMutexLocker locker(&mutex); stopped = true;
}
Одна из проблем применения мьютексов возникает из-за доступности переменной только для одного потока. В программах со многими потоками, пытающимися одновременно читать одну и ту же переменную (не модифицируя ее), мьютекс может серьезно снижать производительность
<< назад вперед >>