Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Название:Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2012
- Город:Москва
- ISBN:978-5-94074-448-1
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ краткое содержание
Книга «Параллельное программирование на С++ в действии» не предполагает предварительных знаний в этой области. Вдумчиво читая ее, вы научитесь писать надежные и элегантные многопоточные программы на С++11. Вы узнаете о том, что такое потоковая модель памяти, и о том, какие средства поддержки многопоточности, в том числе запуска и синхронизации потоков, имеются в стандартной библиотеке. Попутно вы познакомитесь с различными нетривиальными проблемами программирования в условиях параллелизма.
Параллельное программирование на С++ в действии. Практика разработки многопоточных программ - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Я надеюсь, что в этом кратком введении в новые языковые средства мне все же удалось объяснить, как они соотносятся с библиотекой Thread Library, и что с его помощью вы сможете писать и понимать многопоточный код, в котором эти средства используются. Но не забывайте, что это отнюдь не полный справочник и не учебник по использованию новых возможностей языка. Если вы намерены активно пользоваться ими, то рекомендую приобрести достаточно подробную книгу, которая позволит задействовать их в полной мере.
Приложение В.
Краткое сравнение библиотек для написания параллельных программ
Поддержка параллелизма и многопоточности в языках программирования и библиотеках не является чем-то новым, хотя включение ее в стандарт С++ — действительно новшество. Например, в Java многопоточность поддерживалась уже в самой первой версии; на платформах, согласованных со стандартом POSIX, имеется интерфейс из языка С к средствам многопоточности, предоставляемым операционной системой, а язык Erlang поддерживает параллелизм на основе передачи сообщений. Существуют даже библиотеки классов для С++, например Boost, которые обертывают программный интерфейс к средствам многопоточности, существующим на данной платформе (будь то интерфейс POSIX С или нечто иное) и тем самым предоставляют переносимый интерфейс для всех поддерживаемых платформ.
Для тех, кто уже имеет опыт написания многопоточных приложений и хотел бы воспользоваться им для разработки программ на С++ с применением новых возможностей, в этом приложении проводится сравнение средств, имеющихся в Java, POSIX С, С++ с библиотекой Boost Thread Library и С++11. Даются также перекрестные ссылки на соответствующие главы этой книги.
Средство | Java | Posix C | Boost Threads | C++11 | Глава |
---|---|---|---|---|---|
Запуск потоков | Класс java.lang.thread |
Тип pthread_t и соответствующие функции API: pthread_create() , pthread_detach() , pthread_join() |
Класс boost::thread и его функции-члены |
Класс std::thread и его функции-члены |
Глава 2 |
Взаимное исключение | Блоки synchronized |
Тип pthread_mutex_t и соответствующие функции API: pthread_mutex_lock() , pthread_mutex_unlock() и другие |
Класс boost::mutex и его функции-члены, шаблоны boost::lock_guard<> и boost::unique_lock<> |
Класс std::mutex и его функции-члены, шаблоны std::lock_guard<> и std::unique_lock<> |
Глава 3 |
Ожидание предиката | Методы wait() и notify() класса java.lang.Object , используемые внутри блоков synchronized |
Тип pthread_cond_t и соответствующие функции API: pthread_cond_wait() , pthread_cond_timed_wait() и другие |
Классы boost::condition_variable и boost::condition_variable_any и их функции-члены |
Классы std::condition_variable и std::condition_variable_any и их функции-члены |
Глава 4 |
Атомарные операции и модель памяти с учетом параллелизма | volatile -переменные, типы в пакете java.util.concurrent.atomic |
Отсутствует | Отсутствует | Типы std::atomic_xxx , шаблон класса std::atomic<> , функция std::atomic_thread_fence() |
Глава 5 |
Потокобезопасные контейнеры | Контейнеры в пакете java.util.concurrent . |
Отсутствует | Отсутствует | Отсутствует | Главы 6 и 7 |
Будущие результаты | Интерфейс java.util.concurrent.future и ассоциированные с ним классы |
Отсутствует | Шаблонные классы boost::unique_future<> и boost::shared_future<> |
Шаблонные классы std::future<> , std::shared_future<> , и std::atomic_future<> |
Глава 9 |
Пулы потоков | Класс java.util.concurrent.ThreadPoolExecutor |
Отсутствует | Отсутствует | Отсутствует | Глава 9 |
Прерывание потока | Метод interrupt() класса java.lang.Thread |
pthread_cancel() |
Функция-член interrupt() класса boost::thread |
Отсутствует |
Приложение С.
Каркас передачи сообщений и полный пример программы банкомата
В разделе 4.1 мы познакомились с каркасом передачи сообщений между потоками, продемонстрировав его на примере программы банкомата. В этом приложении приводится полный код примера, включая и код каркаса передачи сообщений.
В листинге С.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_):←┘
из указателя на очередь
Интервал:
Закладка: