Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Параллельное программирование над общей памятью. POSIX Threads

Покупка
Основная коллекция
Артикул: 778159.01.99
В учебном пособии приводится описание прикладного программного интерфейса POSIX Threads, рассматриваются примеры разработки и отладки параллельных программ на его основе, содержится лабораторный практикум.
Арыков, С. Б. Параллельное программирование над общей памятью. POSIX Threads : учебное пособие / С. Б. Арыков, М. А. Городничев, Г. А. Щукин. - Новосибирск : Изд-во НГТУ, 2018. - 87 с. - ISBN 978-5-7782-3642-4. - Текст : электронный. - URL: https://znanium.com/catalog/product/1866911 (дата обращения: 06.05.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Министерство образования и науки Российской Федерации 

НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ 
__________________________________________________________________________ 
 
 
 
С.Б. АРЫКОВ, М.А. ГОРОДНИЧЕВ, Г.А. ЩУКИН 
 
 
 
 
ПАРАЛЛЕЛЬНОЕ  
ПРОГРАММИРОВАНИЕ 
НАД ОБЩЕЙ ПАМЯТЬЮ 
 
 
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 

5. ЛАБОРАТОРНЫЙ ПРАКТИКУМ .................................................................. 67 
Команды операционной системы .................................................................... 67 
Исследование производительности  параллельных программ ..................... 70 
Лабораторная работа № 1. Программирование независимых потоков ........ 75 
Лабораторная работа № 2. Программирование взаимодействующих 
потоков ................................................................. 77 
Лабораторная работа № 3. Отладка многопоточных программ ................... 79 
Подготовка отчета по лабораторной работе ................................................... 80 
Дополнительная литература ............................................................................ 82 
Библиографический список ................................................................................. 83 
Приложение А. Шаблон титульного листа отчета  о лабораторной  
работе ......................................................................................... 84 
Приложение Б. Требования к оформлению отчета ............................................ 85 
 
 

ПРЕДИСЛОВИЕ 
 
Пособие предназначено для студентов дневной формы обучения 
факультета прикладной математики и информатики НГТУ направлений подготовки 01.03.02 «Прикладная математика и информатика» 
(дисциплина «Основы параллельного программирования») и 02.03.03 
«Математическое обеспечение и администрирование информационных 
систем» (дисциплина «Параллельное программирование»). 
Учебное пособие содержит введение в проблематику параллельного программирования с использованием прикладного программного 
интерфейса POSIX Threads. В разделах 1–3 содержится подробное 
описание функций POSIX Threads с примерами использования. Рассматриваются вопросы создания и завершения потоков, управления 
атрибутами потоков, синхронизации потоков с помощью различных 
примитивов синхронизации, а также модель планирования потоков и 
управление политиками планирования. В конце каждого раздела приводится список дополнительной литературы для более глубокого изучения материала. 
Раздел 4 посвящен отладке многопоточных программ и включает 
как теоретическую часть (информацию по основным ошибкам при 
разработке многопоточных программ, типовым ошибкам при использовании POSIX Threads, инструментальным средствам для поиска и 
устранения ошибок), так и практические примеры использования отладчика GDB для обнаружения ошибок. 
В разделе 5 представлен лабораторный практикум. Он ориентирован на закрепление теоретических знаний и развитие практических 
навыков использования POSIX Threads для решения задач системного 
параллельного программирования. Каждая лабораторная работа содержит материал, структурированный определенным образом: цель 
работы, порядок ее выполнения, варианты заданий для самостоятельной работы, контрольные вопросы. Кроме лабораторных работ раздел 
содержит методическую информацию о компиляции параллельных 

программ и часто используемых командах ОС Linux при работе с параллельными программами, а также о правилах подготовки отчетов.  
В пособии не рассматриваются некоторые аспекты POSIX Threads, 
которые не входят в программы учебных дисциплин «Основы параллельного программирования» и «Параллельное программирование».  
В частности, опущены вопросы, связанные с отменой потоков и точками отмены, работой с ключами данных, статической инициализацией 
объектов POSIX Threads, некоторыми атрибутами объектов синхронизации. 
Для успешного овладения материалом пособия необходимы базовые знания языка C или C++ и опыт программирования в ОС Linux. 
В результате изучения материала пособия студент должен: 
знать 
 основные функции POSIX Threads; 
 основные примитивы синхронизации для разработки многопоточных программ; 
 основные ошибки многопоточного программирования; 
уметь 
 применять функции POSIX Threads для управления потоками, 
синхронизации потоков, планирования потоков; 
 создавать законченные параллельные программы на основе 
POSIX Threads; 
владеть 
 методами параллельного программирования для разработки прикладного и системного программного обеспечения; 
 навыками применения отладчика GDB для поиска ошибок в параллельных программах. 
 
 
 

ВВЕДЕНИЕ 
 
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.  

Т а б л и ц а  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 в основном использует мьютексы для защиты ресурсов и условные переменные для информирования потоков о событиях. Мьютекс позволяет 
потоку «захватить» разделяемые ресурсы на время работы с ними, так 
что другие потоки не смогут получить к ним доступ. Условная переменная позволяет потоку ожидать, пока разделяемые ресурсы перейдут 

в какое-либо желаемое состояние (например, «очередь пуста» или «ресурс доступен»). 
 Планирование потоков. Функции позволяют изменять политику 
планирования, приоритет потока, способ конкуренции за ресурсы процессора. 
 Вспомогательные функции. Сюда входят функции определения 
идентификатора текущего потока и сравнения идентификаторов потоков, однократное выполнение заданной функции при инициализации 
приложения и ряд других функций. 
Pthreads предлагает стандартизированный подход к способу информирования об ошибках. Все функции Pthreads возвращают ноль в 
случае успеха. Если функция завершается с ошибкой, возвращается 
код ошибки – положительное значение, определенное в файле 
<errno.h>. 
Для общего знакомства с Pthreads можно использовать книги [1–3]. 
Для глубокого и всестороннего изучения темы рекомендуется обратиться к оригинальной спецификации [7] и книге [8]. Для знакомства с 
теорией параллельного программирования рекомендуется книга [4]. 
 
 
 

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++ этот поток исполняет также конструкторы и деструкторы глобальных объектов. 

 start_routine – функция, которую будет исполнять создаваемый 
поток; 
 arg – единственный аргумент, который будет передан в функцию 
start_routine; если в аргументе нет необходимости, необходимо 
указывать NULL. 

Сообщения об ошибках: 
 ноль – ошибки отсутствуют; 
 EAGAIN – недостаточно ресурсов для создания потока либо превышен лимит максимального количества потоков в процессе; 
 EPERM – недостаточно прав доступа, чтобы установить требуемые 
параметры планирования или политику планирования (подробнее 
см. раздел 3). 
Созданный поток может также создавать новые потоки. При этом 
между потоками нет какой-либо иерархии или зависимостей по умолчанию. 
Завершить работу потока позволяет функция pthread_exit(). 
Она также позволяет передать некоторое значение через область памяти, на которую указывает единственный параметр функции. Например, 
таким образом можно передать статус завершения потока.  

Прототип функции: 

void pthread_exit(void *value_ptr); 

Параметры функции: 
 value_ptr – указатель на значение, которое необходимо передать 
(нельзя передавать указатель на локальную переменную потока, 
так как она будет уничтожена при завершении работы потока), либо NULL. 

Сообщения об ошибках: 
 отсутствуют. 
В случае, если основной поток заканчивает свою работу, все потоки будут принудительно завершены. Вызов функции pthread_exit() 
в конце функции main() позволяет дождаться завершения работы всех 
потоков прежде, чем завершится работа программы. 
Пример 1 иллюстрирует создание нового потока, который выводит 
сообщение на экран. 

Пример 1. Создание потока 

#include <cstdlib> 
#include <iostream> 
#include <cstring> 
#include <pthread.h> 
 
using namespace std; 
 
/* Функция, которую будет исполнять созданный поток */ 
void *thread_job(void *arg) 
{ 
    cout << "Thread is running..." << endl; 
} 
 
int main() 
{ 
        // Определяем переменные: идентификатор потока и код ошибки 
    pthread_t thread; 
    int err; 
        // Создаём поток 
    err =  pthread_create(&thread, NULL, thread_job, NULL); 
        // Если при создании потока произошла ошибка, выводим  
        // сообщение об ошибке и прекращаем работу программы 
    if(err != 0) { 
        cout << "Cannot create a thread: " << strerror(err) << endl; 
        exit(-1); 
    } 
        // Ожидаем завершения созданного потока перед завершением  
        // работы программы 
    pthread_exit(NULL); 
} 

АТРИБУТЫ ПОТОКОВ 

Атрибуты потока позволяют менять его свойства. Они определяются только во время создания потока и не могут быть изменены 
позднее.