Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Объекты

mutex
блокируются и разблокируются, используя несколько различных стратегий блокировки, самой простой из которых является блокировка
scoped_lock
.
scoped_lock
— это класс, при конструировании объекта которого используется аргумент типа
mutex
, блокируемый до тех пор, пока не будет уничтожена блокировка
lock
. Рассмотрим функцию-член
enqueue
в примере 12.2, которая показывает, как
scoped_lock
работает совместно с мьютексом
mutex_
.

void enqueue(const T& x) {

 boost::mutex::scoped_lock lock(mutex_);

 list_.push_back(x);

} //
разблокировано!

Когда

lock
уничтожается,
mutex_
разблокируется. Если
lock
конструируется для объекта
mutex
, который уже заблокирован другим потоком, текущий поток переходит в состояние ожидания до тех пор, пока
lock
не окажется доступен.

Такой подход поначалу может показаться немного странным: а почему бы мьютексу

mutex
не иметь методы
lock
и
unlock
? Применение класса
scoped_lock
, который обеспечивает блокировку при конструировании и разблокировку при уничтожении, на самом деле более удобно и менее подвержено ошибкам. Когда вы создаете блокировку, используя
scoped_lock
, мьютекс блокируется на весь период существования объекта
scoped_lock
, т.е. вам не надо ничего разблокировать в явной форме на каждой ветви вычислений. С другой стороны, если вам приходится явно разблокировать захваченный мьютекс, необходимо гарантировать перехват любых исключений, которые могут быть выброшены в вашей функции (или где-нибудь выше ее в стеке вызовов), и гарантировать разблокировку
mutex
. При использовании
scoped_lock
, если выбрасывается исключение или функция возвращает управление, объект
scoped_lock
автоматически уничтожается и
mutex
разблокируется.

Использование мьютекса позволяет сделать всю работу, однако хочется немного большего. При таком подходе нет различия между чтением и записью, что существенно, так как неэффективно заставлять потоки ждать в очереди доступа к ресурсу, когда многие из них выполняют только операции чтения, для которых не требуется монопольный доступ. Для этого в библиотеке Boost Threads предусмотрен класс

read_write_mutex
. Пример 12.3 показывает, как можно реализовать пример 12.2, используя
read_write_mutex
с функцией-членом
front
, которая позволяет вызывающей программе получить копию первого элемента очереди без его выталкивания.

Пример 12.3. Использование мьютекса чтения/записи

#include <iostream>

#include <boost/thread/thread.hpp>

#include <boost/thread/read_write_mutex.hpp>

#include <string>

template<typename T>

class Queue {

 public:

 Queue : // Использовать мьютекс чтения/записи и придать ему приоритет

// записи

 rwMutex_(boost::read_write_scheduling_policy::writer_priority) {}

 ~Queue {}

 void enqueue(const T& x) {

//
Использовать блокировку чтения/записи, поскольку enqueue

// обновляет состояние

boost::read_write_mutex::scoped_write_lock writeLock(rwMutex_);

list_.push_back(x);

 }

 T dequeue {

// Снова использовать блокировку для записи

boost::read_write_mutex::scoped_write_lock writeLock(rwMutex_);

if (list_.empty)

throw "empty!";

T tmp = list_.front;

list_.pop_front;

return(tmp);

 }

 T getFront {

// Это операция чтения, поэтому требуется блокировка только для чтения

boost::read_write_mutex::scoped_read_lock.readLock(rwMutex_);

if (list_.empty)

throw "empty!";

return(list_.front);

 }

private:

 std::list<T> list_;

 boost::read_write_mutex rwMutex_;

};

Queue<std::string> queueOfStrings;

void sendSomething {

 std::string s;

 for (int i = 0, i < 10; ++i) {

queueOfStrings.enqueue("Cyrus");

 }

}

void checkTheFront {

 std::string s;

 for (int i=0; i < 10; ++i) {

try {

s = queueOfStrings.getFront;

} catch(...) {}

 }

}

int main {

 boost::thread thr1(sendSomething);

 boost::thread_group grp;

 grp.сreate_thread(checkTheFront);

 grp.create_thread(checkTheFront);

 grp.сreate_thread(checkTheFront);

 grp_create_thread(checkTheFront);

 thr1.join;

 grp.join_all;

}

Здесь необходимо отметить несколько моментов. Обратите внимание, что теперь я использую

read_write_mutex
.

boost::read_write_mutex rwMutex_;

При использовании мьютексов чтения/записи блокировки тоже выполняются иначе. В примере 12.3, когда мне нужно заблокировать

Queue
для записи, я создаю объект класса
scoped_write_lock
.

boost::read_write_mutex::scoped_write_lock writeLock(rwMutex_);

Поделиться:
Популярные книги

Вонгозеро

Вагнер Яна
1. Вонгозеро
Детективы:
триллеры
9.19
рейтинг книги
Вонгозеро

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

Титан империи 8

Артемов Александр Александрович
8. Титан Империи
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Титан империи 8

Ведьма Вильхельма

Шёпот Светлана
Любовные романы:
любовно-фантастические романы
8.67
рейтинг книги
Ведьма Вильхельма

Волхв

Земляной Андрей Борисович
3. Волшебник
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волхв

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Темный Патриарх Светлого Рода

Лисицин Евгений
1. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода

Пистоль и шпага

Дроздов Анатолий Федорович
2. Штуцер и тесак
Фантастика:
альтернативная история
8.28
рейтинг книги
Пистоль и шпага

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя