Параллельное программирование над общей памятью. POSIX Threads. Учебное пособие
.pdfМинистерство образования и науки Российской Федерации
НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
__________________________________________________________________________
С.Б. АРЫКОВ, М.А. ГОРОДНИЧЕВ, Г.А. ЩУКИН
ПАРАЛЛЕЛЬНОЕ
ПРОГРАММИРОВАНИЕ НАД ОБЩЕЙ ПАМЯТЬЮ
POSIX THREADS
Утверждено Редакционно-издательским советом университета в качестве учебного пособия
НОВОСИБИРСК
2018
УДК 004.424.032.24 (075.8) А 895
Рецензенты:
д-р техн. наук, профессор Б.М. Глинский канд. техн. наук, доцент В.П. Маркова
Работа подготовлена на кафедре параллельных вычислительных технологий для студентов ФПМИ направлений «Прикладная математика и информатика» и «Математическое обеспечение и администрирование информационных систем»
Арыков С.Б.
А 895 Параллельное программирование над общей памятью. POSIX Threads: учебное пособие / С.Б. Арыков, М.А. Городничев, Г.А. Щукин. – Новосибирск: Изд-во НГТУ, 2018. – 87 с.
ISBN 978-5-7782-3642-4
В учебном пособии приводится описание прикладного программного интерфейса POSIX Threads, рассматриваются примеры разработки и отладки параллельных программ на его основе, содержится лабораторный практикум.
|
УДК 004.424.032.24 (075.8) |
ISBN 978-5-7782-3642-4 |
© Арыков С.Б., Городничев М.А., |
|
Щукин Г.А., 2018 |
|
© Новосибирский государственный |
|
технический университет, 2018 |
ОГЛАВЛЕНИЕ
Предисловие............................................................................................................ |
5 |
Введение.................................................................................................................. |
7 |
1. МНОГОПОТОЧНАЯ ПРОГРАММА.............................................................. |
10 |
Создание и завершение работы потоков......................................................... |
10 |
Атрибуты потоков............................................................................................. |
12 |
Присоединяемые и отсоединенные потоки.................................................... |
16 |
Передача параметров в потоки........................................................................ |
18 |
Прочие функции................................................................................................ |
19 |
Дополнительная литература ............................................................................ |
20 |
2. СИНХРОНИЗАЦИЯ ПОТОКОВ..................................................................... |
22 |
Мьютексы.......................................................................................................... |
22 |
Спинлоки........................................................................................................... |
29 |
Барьеры.............................................................................................................. |
31 |
Условные переменные...................................................................................... |
35 |
Дополнительная литература ............................................................................ |
42 |
3. ПЛАНИРОВАНИЕ ПОТОКОВ....................................................................... |
43 |
Модель планирования потоков........................................................................ |
43 |
Политики планирования................................................................................... |
44 |
Распределение процессорного времени.......................................................... |
46 |
Дополнительная литература ............................................................................ |
47 |
4. ОТЛАДКА МНОГОПОТОЧНЫХ ПРОГРАММ............................................ |
48 |
Типовые ошибки многопоточных программ.................................................. |
48 |
Особенности использования POSIX Threads.................................................. |
49 |
Инструменты отладки многопоточных программ......................................... |
50 |
Отладка многопоточных программ с помощью GDB ................................... |
51 |
Примеры сеансов работы с GDB ..................................................................... |
58 |
Дополнительная литература ............................................................................ |
66 |
3 |
|
5. ЛАБОРАТОРНЫЙ ПРАКТИКУМ.................................................................. |
67 |
Команды операционной системы.................................................................... |
67 |
Исследование производительности параллельных программ..................... |
70 |
Лабораторная работа № 1. Программирование независимых потоков........ |
75 |
Лабораторная работа № 2. Программирование взаимодействующих |
|
потоков................................................................. |
77 |
Лабораторная работа № 3. Отладка многопоточных программ................... |
79 |
Подготовка отчета по лабораторной работе................................................... |
80 |
Дополнительная литература ............................................................................ |
82 |
Библиографический список................................................................................. |
83 |
Приложение А. Шаблон титульного листа отчета о лабораторной |
|
работе ......................................................................................... |
84 |
Приложение Б. Требования к оформлению отчета............................................ |
85 |
4
ПРЕДИСЛОВИЕ
Пособие предназначено для студентов дневной формы обучения факультета прикладной математики и информатики НГТУ направлений подготовки 01.03.02 «Прикладная математика и информатика» (дисциплина «Основы параллельного программирования») и 02.03.03 «Математическое обеспечение и администрирование информационных систем» (дисциплина «Параллельное программирование»).
Учебное пособие содержит введение в проблематику параллельного программирования с использованием прикладного программного интерфейса POSIX Threads. В разделах 1–3 содержится подробное описание функций POSIX Threads с примерами использования. Рассматриваются вопросы создания и завершения потоков, управления атрибутами потоков, синхронизации потоков с помощью различных примитивов синхронизации, а также модель планирования потоков и управление политиками планирования. В конце каждого раздела приводится список дополнительной литературы для более глубокого изучения материала.
Раздел 4 посвящен отладке многопоточных программ и включает как теоретическую часть (информацию по основным ошибкам при разработке многопоточных программ, типовым ошибкам при использовании POSIX Threads, инструментальным средствам для поиска и устранения ошибок), так и практические примеры использования отладчика GDB для обнаружения ошибок.
В разделе 5 представлен лабораторный практикум. Он ориентирован на закрепление теоретических знаний и развитие практических навыков использования POSIX Threads для решения задач системного параллельного программирования. Каждая лабораторная работа содержит материал, структурированный определенным образом: цель работы, порядок ее выполнения, варианты заданий для самостоятельной работы, контрольные вопросы. Кроме лабораторных работ раздел содержит методическую информацию о компиляции параллельных
5
программ и часто используемых командах ОС Linux при работе с параллельными программами, а также о правилах подготовки отчетов.
Впособии не рассматриваются некоторые аспекты POSIX Threads, которые не входят в программы учебных дисциплин «Основы параллельного программирования» и «Параллельное программирование».
Вчастности, опущены вопросы, связанные с отменой потоков и точками отмены, работой с ключами данных, статической инициализацией объектов POSIX Threads, некоторыми атрибутами объектов синхронизации.
Для успешного овладения материалом пособия необходимы базовые знания языка C или C++ и опыт программирования в ОС Linux.
Врезультате изучения материала пособия студент должен:
знать
основные функции POSIX Threads;
основные примитивы синхронизации для разработки многопоточных программ;
основные ошибки многопоточного программирования;
уметь
применять функции POSIX Threads для управления потоками, синхронизации потоков, планирования потоков;
создавать законченные параллельные программы на основе
POSIX Threads;
владеть
методами параллельного программирования для разработки прикладного и системного программного обеспечения;
навыками применения отладчика GDB для поиска ошибок в параллельных программах.
6
ВВЕДЕНИЕ
POSIX (англ. Portable Operating System Interface) – международный набор стандартов, зафиксированный в документе ISO/IEC/IEEE 9945:2009 Information technology – Portable Operating System Interface (POSIX®) Base Specifications, Issue 7 (бесплатная версия стандарта,
поддерживаемая Open Group, доступна в [7]) и описывающий интерфейсы между операционной системой и прикладной программой. Его составной частью является раздел «XSH. System Interfaces», который в том числе определяет прикладной программный интерфейс (англ. API, application programing interface) для управления потоками. Этот API
называют POSIX Threads или, для краткости, Pthreads.
Pthreads реализован на большом количестве платформ, его использование обеспечивает высокий уровень переносимости программного кода, поэтому часто Pthreads используется для системного программирования. Другими достоинствами Pthreads являются возможность создания приложений, которые исполняются существенно быстрее на многопроцессорных / многоядерных компьютерах; возможность использования системных ресурсов эффективнее; обеспечение большей дружественности для пользователя.
Pthreads определяет программный интерфейс для языка программирования C. Структурно он состоит из специализированных типов данных и набора функций, предоставляющих возможность многопоточного программирования – такого подхода к дизайну приложения, когда оно представляется в виде множества потоков и разрешается их параллельное исполнение. Здесь поток – это последовательность команд, которая может быть запланирована на исполнение операционной системой.
Основные типы данных Pthreads представлены в табл. 1.
7
Таблица 1
Основные типы данных Pthreads
Название типа данных |
Описание |
pthread_t |
Идентификатор потока |
pthread_attr_t |
Атрибуты потока |
pthread_mutex_t |
Мьютекс |
pthread_mutexattr_t |
Атрибуты мьютекса |
pthread_cond_t |
Условная переменная |
pthread_condattr_t |
Атрибуты условной переменной |
pthread_barrier_t |
Барьер |
pthread_barrierattr_t |
Атрибуты барьера |
pthread_spinlock_t |
Спинлок |
pthread_once_t |
Однократно инициализируемая структура |
|
управления |
Все типы данных считаются «непрозрачными», что означает отсутствие официального определения этих типов. Чтобы дополнительно подчеркнуть этот факт, в документации они именуются объектами. Программист никогда не должен делать предположений относительно их внутренней реализации. Например, идентификатор потока (тип pthread_t) может быть реализован как целое число, указатель на целое число или структура. Поэтому программный код, предполагающий, например, что идентификатор потока – это число, будет некорректным. Для разработки переносимого программного кода необходимо для доступа к данным, имеющим один из типов Pthreads, использовать функции, предоставляемые Pthreads.
Функции Pthreads можно объединить в логические группы.
Управление потоками. Сюда входят функции, которые непосредственно работают с потоками: создание, отсоединение, работа с атрибутами потока.
Синхронизация потоков. Модель синхронизации Pthreads в основном использует мьютексы для защиты ресурсов и условные переменные для информирования потоков о событиях. Мьютекс позволяет потоку «захватить» разделяемые ресурсы на время работы с ними, так что другие потоки не смогут получить к ним доступ. Условная переменная позволяет потоку ожидать, пока разделяемые ресурсы перейдут
8
в какое-либо желаемое состояние (например, «очередь пуста» или «ресурс доступен»).
Планирование потоков. Функции позволяют изменять политику планирования, приоритет потока, способ конкуренции за ресурсы процессора.
Вспомогательные функции. Сюда входят функции определения идентификатора текущего потока и сравнения идентификаторов потоков, однократное выполнение заданной функции при инициализации приложения и ряд других функций.
Pthreads предлагает стандартизированный подход к способу информирования об ошибках. Все функции Pthreads возвращают ноль в случае успеха. Если функция завершается с ошибкой, возвращается код ошибки – положительное значение, определенное в файле
<errno.h>.
Для общего знакомства с Pthreads можно использовать книги [1–3]. Для глубокого и всестороннего изучения темы рекомендуется обратиться к оригинальной спецификации [7] и книге [8]. Для знакомства с теорией параллельного программирования рекомендуется книга [4].
9
1. МНОГОПОТОЧНАЯ ПРОГРАММА
СОЗДАНИЕ И ЗАВЕРШЕНИЕ РАБОТЫ ПОТОКОВ
При запуске на исполнение программы, использующей Pthreads, создается новый процесс c единственным (основным) потоком, исполняющим функцию main()1. Остальные потоки должны быть созданы программистом самостоятельно.
Функция pthread_create() позволяет добавить новый поток к текущему процессу.
Прототип функции:
int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*),
void *restrict arg);
Параметры функции:
thread – идентификатор созданного потока (указатель на область памяти, в которой в случае успешного создания потока размещается объект типа pthread_t, идентифицирующий поток);
attr – атрибуты (указатель на переменную типа pthread_attr_t), которые получит поток; если указано NULL, то поток получит атрибуты по умолчанию: неограниченный, присоединяемый, имеющий приоритет родителя и размер стека по умолчанию (более подробная информация об атрибутах потока приведена в разделе «Атрибуты потоков»);
1 В C++ этот поток исполняет также конструкторы и деструкторы глобальных объектов.
10
