Предположим, что нам нужно обеспечить защиту переменной
private:
QMutex mutex;
…
};
Функция
01 void Thread::run
02 {
03 forever {
04 mutex.lock;
05 if (stopped) {
06 stopped = false;
07 mutex.unlock;
08 break;
09 }
10 mutex.unlock;
11 cerr << qPrintable(messageStr.ascii);
12 }
13 cerr << endl;
14 }
Функция
01 void Thread::stop
02 {
03 mutex.lock;
04 stopped = true;
05 mutex.unlock;
06 }
Блокировка и разблокировка мьютекса в сложных функциях или там, где обрабатываются исключения С++, может иметь ошибки. Qt предлагает удобный класс
01 void Thread::run
02 {
03 forever {
04 {
05 QMutexLocker locker(&mutex);
06 if (stopped) {
07 stopped = false;
08 break;
09 }
10 }
11 cerr << qPrintable(messageStr);
12 }
13 cerr << endl;
14 }
15 void Thread::stop
16 {
17 QMutexLocker locker(&mutex);
18 stopped = true;
18 }
Одна из проблем применения мьютексов возникает из-за доступности переменной только для одного потока. В программах со многими потоками, пытающимися одновременно читать одну и ту же переменную (не модифицируя ее), мьютекс может серьезно снижать производительность. В этих случаях мы можем использовать
В классе
01 MyData data;
02 QReadWriteLock lock;
03 void ReaderThread::run
04 {
05 …
06 lock.lockForRead;
07 access_data_without_modifying_it(&data);
08 lock.unlock;
09 …
10 }
11 void WriterThread::run
12 {
13 …
14 lock.lockForWrite;
15 modify_data(&data);
16 lock.unlock;
17 …
18 }
Ради удобства мы можем использовать классы
Класс
• QSemaphore semaphore(1) — QMutex mutex,
• Semaphore.acquire — mutex.lock,
• Semaphore.release — mutex.unlock.
Передавая 1 конструктору, мы указываем семафору на то, что он управляет работой одного ресурса. Преимущество применения семафора заключается в том, что мы можем передавать конструктору числа, отличные от 1, и затем вызывать функцию
Типичная область применения семафоров — это передача некоторого количества данных