Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Название:Параллельное программирование на С++ в действии. Практика разработки многопоточных программ
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год: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_):←┘ из указателя на очередь
Интервал:
Закладка: