Читаем C++. Сборник рецептов полностью

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

Когда 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

#include

#include

#include

template

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 list_;

 boost::read_write_mutex rwMutex_;

};

Queue 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_;

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных