Читаем Параллельное программирование на С++ в действии полностью

В листинге С.1 показан код очереди сообщений. Сообщения хранятся в списке и представлены указателями на базовый класс. Сообщения конкретного типа обрабатываются шаблонным классом, производным от этого базового класса. В момент помещения сообщения в очередь конструируется подходящий экземпляр обертывающего класса и сохраняется указатель на него; операция извлечения возвращает именно этот указатель. Поскольку в классе message_base нет функций-членов, извлекающий поток должен привести указатель к нужному типу wrapped_message, прежде чем сможет получить хранящееся сообщение.

Листинг С.1. Простая очередь сообщений

#include

#include

#include

#include

namespace messaging

{                     │Базовый класс

struct message_base {←┘элементов очереди

 virtual ~message_base() {}

};

template Для каждого типа сообщений

struct wrapped_message:←┘имеется специализация

message_base {

 Msg contents;

 explicit wrapped_message(Msg const& contents_):

  contents(contents_) {}

};

            │Наша очередь

class queue←┘сообщений

{                                              │В настоящей

 std::mutex m;                                 │очереди хранят-

 std::condition_variable с;                    │ся указатели на

 std::queue > q;←┘message_base

public:

 template               │Обернуть добав-

 void push(T const& msg)            │ленное сообще-

 {                                  │ние и сохранить

  std::lock_guard lk(m);│указатель

  q.push( ←┘

   std::make_shared >(msg));

  с.notify_all();

 }

 std::shared_ptr wait_and_pop()│Блокирует до

 {                                           │появления в

  std::unique_lock lk(m);        │очереди хотя бы

  c.wait(lk, [&]{ return !q.empty(); });    ←┘одного элемента

  auto res = q.front();

  q.pop();

  return res;

 }

};

}

Отправкой сообщений занимается объект класса sender, показанного в листинге С.2. Это не более чем тонкая обертка вокруг очереди сообщений, которая позволяет только добавлять сообщения. При копировании экземпляров sender копируется только указатель на очередь, а не сама очередь.

Листинг С.2. Класс sender

namespace messaging {

 class sender {│sender обертывает указатель

 queue* q;    ←┘на очередь

public:     │У сконструированного по умолчанию

 sender() :←┘sender'a нет очереди

 q(nullptr) {}

                             │Разрешаем конструирование

 explicit sender(queue* q_):←┘из указателя на очередь

  q(q_) {}

 template

 void send(Message const& msg) {

  if (q){        │Отправка сообщения сводится

   q->push(msg);←┘к помещению его в очередь

  }

 }

};

}

Получение сообщений несколько сложнее. Мы не только должны дождаться появления сообщения в очереди, но еще и проверить, совпадает ли его тип с одним из известных нам типов, и вызвать соответствующий обработчик. Эта процедура начинается в классе receiver, показанном в листинге ниже.

Листинг С.3. Класс receiver

namespace messaging {

class receiver {

 queue q; ←receiver владеет очередью

public:              │Разрешить неявное преобразование в объект

 operator sender() {←┘sender, ссылающийся на эту очередь

  return sender(&q);

 }

                     │При обращении к функции ожидания

 dispatcher wait() {←┘очереди создается диспетчер

  return dispatcher(&q);

 }

};

}

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

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

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

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

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

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

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

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

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

Все жанры