Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Название:Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-448-1
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ краткое содержание
Книга «Параллельное программирование на С++ в действии» не предполагает предварительных знаний в этой области. Вдумчиво читая ее, вы научитесь писать надежные и элегантные многопоточные программы на С++11. Вы узнаете о том, что такое потоковая модель памяти, и о том, какие средства поддержки многопоточности, в том числе запуска и синхронизации потоков, имеются в стандартной библиотеке. Попутно вы познакомитесь с различными нетривиальными проблемами программирования в условиях параллелизма.
Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
account = msg.account;
pin = "";
interface_hardware.send(display_enter_pin());
state = &atm::getting_pin;
}
);
}
void done_processing() {
interface_hardware.send(eject_card());
state = &atm::waiting_for_card;
}
atm(atm const&) = delete;
atm& operator=(atm const&) = delete;
public:
atm(messaging::sender bank_,
messaging::sender interface_hardware_):
bank(bank_), interface_hardware(interface_hardware_) {}
void done() {
get_sender().send(messaging::close_queue());
}
void run() {
state = &atm::waiting_for_card;
try {
for (;;) {
(this->*state)();
}
} catch(messaging::close_queue const&) {
}
}
messaging::sender get_sender() {
return incoming;
}
};
Листинг С.8.Конечный автомат банка
class bank_machine {
messaging::receiver incoming;
unsigned balance;
public:
bank_machine():
balance(199) {}
void done() {
get_sender().send(messaging::close_queue());
}
void run() {
try {
for (;;) {
incoming.wait().handle(
[&](verify_pin const& msg) {
if (msg.pin == "1937") {
msg.atm_queue.send(pin_verified());
} else {
msg.atm_queue.send(pin_incorrect());
}
}
).handle(
[&](withdraw const& msg) {
if (balance >= msg.amount) {
msg.atm_queue.send(withdraw_ok());
balance -= msg.amount;
} else {
msg.atm_queue.send(withdraw_denied());
}
}
).handle(
[&](get_balance const& msg) {
msg.atm_queue.send(::balance(balance));
}
).handle(
[&](withdrawal_processed const& msg) {
}
).handle(
[&](cancel_withdrawal const& msg) {
}
);
}
} catch(messaging::close_queue const&) {
}
}
messaging::sender get_sender() {
return incoming;
}
};
Листинг С.9.Конечный автомат пользовательского интерфейса
class interface_machine {
messaging::receiver incoming;
public:
void done() {
get_sender().send(messaging::close_queue());
}
void run() {
try {
for (;;) {
incoming.wait().handle (
[&](issue_money const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Issuing "
<< msg.amount << std::endl;
}
}
).handle(
[&](display_insufficient_funds const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Insufficient funds" << std::endl;
}
}
).handle(
[&](display_enter_pin const& msg) {
{
std::lock_guard lk(iom);
std::cout
<< "Please enter your PIN (0-9)" << std::endl;
}
}
).handle(
[&](display_enter_card const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Please enter your card (I)"
<< std::endl;
}
}
).handle(
[&](display_balance const& msg) {
{
std::lock_guard lk(iom);
std::cout
<< "The balance of your account is "
<< msg.amount << std::endl;
}
}
).handle(
[&](display_withdrawal_options const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Withdraw 50? (w)" << std::endl;
std::cout << "Display Balance? (b)"
<< std::endl;
std::cout << "Cancel? (c) " << std::endl;
}
}
).handle(
[&](display_withdrawal_cancelled const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Withdrawal cancelled"
<< std::endl;
}
}
).handle(
[&](display_pin_incorrect_message const& msg) {
{
std::lock_guard lk(iom);
std::cout << "PIN incorrect" << std::endl;
}
}
).handle(
[&](eject_card const& msg) {
{
std::lock_guard lk(iom);
std::cout << "Ejecting card" << std::endl;
}
}
);
}
} catch (messaging::close_queue&) {
}
}
messaging::sender get_sender() {
return incoming;
}
};
Листинг С.10.Управляющая программа
int main() {
bank_machine bank;
interface_machine interface_hardware;
atm machine(bank.get_sender(), interface_hardware.get_sender());
std::thread bank_thread(&bank_machine::run, &bank);
std::thread if_thread(&interface_machine::run,
&interface_hardware);
std::thread atm_thread(&atm::run, &machine);
messaging::sender atmqueue(machine.get_sender());
bool quit_pressed = false;
while (!quit_pressed) {
char c = getchar();
switch(с) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
atmqueue.send(digit_pressed(с));
break;
case 'b':
atmqueue.send(balance_pressed());
break;
case 'w':
atmqueue.send(withdraw_pressed(50));
break;
case 'с':
atmqueue.send(cancel_pressed());
break;
case 'q':
quit_pressed = true;
break;
case 'i':
atmqueue.send(card_inserted("acc1234"));
break;
}
}
bank.done();
machine.done();
interface_hardware.done();
atm_thread.join();
bank_thread.join();
if_thread.join();
}
Приложение D
Справочник по библиотеке С++ Thread Library
D.1. Заголовок < chrono >
В заголовке объявлены классы для представления моментов времени, интервалов и часов, которые служат источником объектов time_point
. В каждом классе часов имеется статическая переменная-член is_steady
, показывающая, являются ли данные часы стабильными . Стабильными называются часы, которые ходят с постоянной частотой и не допускают подведения. Единственные гарантированно стабильные часы представлены классом std::chrono::steady_clock
.
Содержимое заголовка
namespace std {
namespace chrono {
template<1>>
class duration;
template<
typename Clock,
typename Duration = typename Clock::duration>
class time_point;
class system_clock;
class steady_clock;
typedef unspecified-clock-type high_resolution_clock;
}
}
D.1.1. Шаблон класса std::chrono::duration
Шаблон класса s td::chrono::duration
предназначен для представления интервалов. Параметры шаблона Rep
и Period
— это соответственно тип данных для хранения значения интервала и конкретизация шаблона класса std::ratio
, которая задает промежуток времени (в виде долей секунды) между последовательными «тиками». Например, std::chrono::duration
определяет количество миллисекунд, представимое значением типа int
, s td::chrono::duration<1, 50>>
— количество пятидесятых долей секунды, представимое значением типа short
, а std::chrono::duration<60, 1>>
— количество минут, представимое значением типа long long
.
Определение класса
template <1> >
class duration {
public:
typedef Rep rep;
typedef Period period;
constexpr duration() = default;
~duration() = default;
duration(const duration&) = default;
duration& operator=(const duration&) = default;
template
constexpr explicit duration(const Rep2& r);
Интервал:
Закладка: