Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - [165]

Шрифт
Интервал

помечен как

>  if (!chained) {                     (5) noexcept(false)

>   wait_and_dispatch();

>  }

> }

>};

>}

Шаблон класса >TemplateDispatcher<> устроен по образцу класса >dispatcher и почти ничем не отличается от него. В частности, деструктор тоже вызывает >wait_and_dispatch(), чтобы дождаться сообщения.

Поскольку мы не возбуждаем исключения, если сообщение обработало, то теперь в цикле (1) нужно проверять, обработали мы сообщение или нет. Обработка прекращается, как только сообщение успешно обработало, чтобы в следующий раз можно было ждать очередного набора сообщений. Если найдено соответствие указанному типу сообщения, то вызывается предоставленная функция (2), а не возбуждается исключение (хотя функция-обработчик может и сама возбудить исключение). Если же соответствие не найдено, то мы передаем сообщение предыдущему диспетчеру в цепочке (3). В самом первом экземпляре это будет объект >dispatcher, но если в функции >handle()(4) вызовы сцеплялись, чтобы можно было обработать несколько типов сообщений, то предыдущим диспетчером может быть ранее созданный экземпляр >TemplateDispatcher<>, который в свою очередь передаст сообщение предшествующему ему диспетчеру в цепочке, если не сможет обработать его сам. Поскольку любой обработчик может возбудить исключение (в том числе и обработчик самого первого объекта >dispatcher, если встретит сообщение >close_queue), то деструктор снова необходимо снабдить аннотацией >noexcept(false)(5).

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

И чтобы закончить пример из главы 4, в листинге С.6 приведён код сообщений, в листингах С.7, С.8 и С.9 — различные конечные автоматы, а в листинге С.10 — управляющая программа.


Листинг С.6. Сообщения банкомата

>struct withdraw {

> std::string account;

> unsigned amount;

> mutable messaging::sender atm_queue;


> withdraw(std::string const& account_,

>  unsigned amount_, messaging::sender atm_queue_):

>   account(account_), amount(amount_), atm_queue(atm_queue_) {}

>};


>struct withdraw_ok {};


>struct withdraw_denied {};


>struct cancel_withdrawal {

> std::string account;

> unsigned amount;


> cancel_withdrawal(std::string const& account_,

>  unsigned amount_):

>   account(account_), amount(amount_) {}

>};


>struct withdrawal_processed {

> std::string account;

> unsigned amount;


> withdrawal_processed(std::string const& account_,

>  unsigned amount_):

>   account(account_), amount(amount_) {}

>};


>struct card_inserted {

> std::string account;


> explicit card_inserted(std::string const& account_):

>  account(account_) {}

>};


>struct digit_pressed {

> char digit;


> explicit digit_pressed(char digit_):

>  digit(digit_) {}

>};


>struct clear_last_pressed {};


>struct eject_card {};


>struct withdraw_pressed {

> unsigned amount;


> explicit withdraw_pressed(unsigned amount_):

>  amount(amount_) {}


>};


>struct cancel_pressed {};


>struct issue_money {

> unsigned amount;

> issue_money(unsigned amount_):

>  amount(amount_) {}

>};


>struct verify_pin {

> std::string account;

> std::string pin;

> mutable messaging::sender atm_queue;


> verify_pin(std::string const& account_, std::string const& pin_,

>  messaging::sender atm_queue_):

>   account(account_), pin(pin_), atm_queue(atm_queue_) {}

>};


>struct pin_verified {};


>struct pin_incorrect {};


>struct display_enter_pin {};


>struct display_enter_card {};


>struct display_insufficient_funds {};


>struct display_withdrawal_cancelled {};


>struct display_pin_incorrect_message {};


>struct display_withdrawal_options (};


>struct get_balance {

> std::string account;

> mutable messaging::sender atm_queue;


> get_balance(

>  std::string const& account_, messaging::sender atm_queue_):

>   account(account_), atm_queue(atm_queue_) {}

>};


>struct balance {

> unsigned amount;


> explicit balance(unsigned amount_):

>  amount(amount_) {}

>};


>struct display_balance {

> unsigned amount;


> explicit display_balance(unsigned amount_):

>  amount(amount_) {}

>};


>struct balance_pressed {};


Листинг С.7. Конечный автомат банкомата

>class atm {

> messaging::receiver incoming;

> messaging::sender bank;

> messaging::sender interface_hardware;

> void (atm::*state)();

> std::string account;

> unsigned withdrawal_amount;

> std::string pin;


> void process_withdrawal() {

>  incoming.wait().handle(

>   [&](withdraw_ok const& msg) {

>    interface_hardware.send(

>     issue_money(withdrawal_amount));

>    bank.send(

>     withdrawal_processed(account, withdrawal_amount));

>    state = &atm::done_processing;

>   }

>  ).handle(

>   [&](withdraw_denied const& msg) {

>    interface_hardware.send(display_insufficient_funds());

>    state = &atm::done_processing;

>   }

>  ).handle(

>   [&](cancel_pressed const& msg) {

>    bank.send(

>     cancel_withdrawal(account, withdrawal_amount));

>    interface_hardware.send(

>     display_withdrawal_cancelled());

>    state = &atm::done_processing;

>   }

>  );

> }


> void process_balance() {

>  incoming.wait().handle(

>   [&](balance const& msg) {

>    interface_hardware.send(display_balance(msg.amount));


Еще от автора Энтони Д Уильямс
Викиномика. Как массовое сотрудничество изменяет всё

Это знаменитый бестселлер, который научит вас использовать власть массового сотрудничества и покажет, как применять викиномику в вашем бизнесе. Переведенная более чем на двадцать языков и неоднократно номинированная на звание лучшей бизнес-книги, "Викиномика" стала обязательным чтением для деловых людей во всем мире. Она разъясняет, как массовое сотрудничество происходит не только на сайтах Wikipedia и YouTube, но и в традиционных компаниях, использующих технологии для того, чтобы вдохнуть новую жизнь в свои предприятия.Дон Тапскотт и Энтони Уильямс раскрывают принципы викиномики и рассказывают потрясающие истории о том, как массы людей (как за деньги, так и добровольно) создают новости, изучают геном человека, создают ремиксы любимой музыки, находят лекарства от болезней, редактируют школьные учебники, изобретают новую косметику, пишут программное обеспечение и даже строят мотоциклы.Знания, ресурсы и вычислительные способности миллиардов людей самоорганизуются и превращаются в новую значительную коллективную силу, действующую согласованно и управляемую с помощью блогов, вики, чатов, сетей равноправных партнеров и личные трансляции.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Программное обеспечение и его разработка

Автор книги — американский специалист по программированию, один из руководителей фирмы IBM, в своей книге делает попытку изложить общие проблемы создания программного обеспечения, его сопровождения и использования. Особенно подробно рассматриваются все фазы разработки программ разных типов. Изложение ясное, удачно иллюстрировано примерами.Для программистов разной квалификации и пользователей ЭВМ.fb2: ВНИМАНИЕ. В тексте присутствуют таблицы. Рекомендуется читать файл с помощью программы, поддерживающей их отображение.


Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса

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


Примеры использования Паттерн Singleton (Одиночка)

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


Создаем порт для FreeBSD своими руками. Часть II

Система сборки программ, используемая во FreeBSD, имеет значительно большие возможности, чем те, которые мы задействовали. Какие это возможности и как их использовать в своих портах?


FreeBSD - полезные советы

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