Лекция по POSIX Threads

advertisement
МО ВВС ИВМ и МГ СО РАН
POSIX Threads
Городничев Максим Александрович
Что такое POSIX Threads
Threads = поток = нить
POSIX = Portable Operating System
Interface for UNIX = Интерфейс
переносимой операционной системы
UNIX
набор стандартов, описывающих
интерфейсы между операционной
системой и прикладной программой.
Многопоточное
программирование
• Используется для создания параллельных программ
для систем с общей памятью
Процессор
Ядро
Ядро
Процессор
Ядро
Ядро
Процессор
Ядро
Ядро
Процессор
Ядро
Ядро
Оперативная память
(с) Киреев С.E.
Процессы и потоки
Процесс – это среда выполнения задачи
(программы).
Процесс создаётся ОС и
содержит информацию о
программных ресурсах и
текущем состоянии
выполнения программы.
(с) Киреев С.E.
Процессы и потоки
Поток – это «облегченный процесс».
• Создается в рамках
процесса,
• Имеет свой поток
управления,
• Разделяет ресурсы
процесса-родителя с
другими потоками,
• Погибает, если
погибает
родительский
процесс.
(с) Киреев С.E.
Зачем использовать несколько
процессов (потоков) в одном
приложении
• распределение работы между процессорами
(ядрами) в мультипроцессорной системе
• одновременное выполнение операций вводавывода с использованием центрального
процессора для решения других частей
задачи
• асинхронная обработка событий
• выполнение задач в соответствии с
приоритетами
Преимущества набора потоков
вместо набора процессов
• Затраты на создание и управление
потоками в операционной системе
гораздо ниже затрат на процессы
• Все потоки в пределах одного процесса
разделяют одно адресное
пространство. Взаимодействие между
потоками реализуется проще, чем
между процессами.
POSIX Threads API
• Управление потоками
• Мьютексы
• Условные переменные
Умножение вектора на вектор
(управление потоками и мьютексы)
#include <pthread.h>
#include <stdio.h>
int globalRes = 0;
int v1[100], v2[100];
int ids[4] = {0,1,2,3};
pthread_t thrs[4];
pthread_mutex_t mutex;
void* prod(void* me)
{
int offset = *((int*)me);
offset *= 25;
int res = 0;
for(int i = offset; i<offset+25; i++)
res += v1[i]*v2[i];
pthread_mutex_lock(&mutex);
globalRes += res;
pthread_mutex_unlock(&mutex);
}
int main()
{
//...инициализация массивов
thread_attr_t attrs;
if(0!=pthread_attr_init(&attrs, NULL))
{ abort() };
pthread_attr_setdetachstate(&attrs,
PTHREAD_CREATE_JOINABLE);
pthread_mutex_init(&mutex, NULL);
for(int i = 0; i<4; i++)
pthread_create(&thrs[i], &attrs, prod, &ids[i]);
pthread_attr_destroy(&attrs);
for(int i = 0; i<4; i++)
pthread_join(thrs[i], NULL);
return 0;
}
Ошибочная передача
параметров
int t;
pthread_t thrs[NUM_THREADS];
for(t=0; t<NUM_THREADS; t++)
{
...
pthread_create(&threads[t], NULL, threadFunc,
(void *) &t);
...
}
Основные виды ошибок
синхронизации:
• Race Condition – состояние гонок
– Неупорядоченное чтение-запись или
запись-запись общей переменной
несколькими потоками – результат
недетерминирован
• Deadlock – взаимная блокировка
– Все потоки ожидают наступления событий,
которые никогда не наступят
Завершение потока
•
•
•
•
Возврат из функции потока
Вызов функции pthread_exit() из потока
Вызов pthread_cancel() другим потоком
Завершение всего процесса через
exec(), exit(), выход из main() через
return.
Условные переменные
ГЛОБАЛЬНЫЕ
ПЕРЕМЕННЫЕ
pthread_mutex_t mutex;
pthread_cond_t cond;
int counter = 0;
ПОТОК НОМЕР 1
pthread_mutex_lock(&mutex);
if(counter!=criticalValue)
pthread_cond_wait(&cond,
&mutex);
processCriticalValue();
pthread_mutex_unlock();
ПОТОК НОМЕР 2
do
{
...
pthread_mutex_lock(&mutex);
doSomethingWith(&counter);
if(counter==criticalValue)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...
}while(...);
Понятие thread-safeness
(«потокобезопасность»)
Код называется потокобезопасным, если
использование его несколькими
потоками без взаимного исключения
корректно.
В разработке многопоточных приложений
важно быть уверенным в том, что
используются потокобезопасные
библиотеки.
Компиляция программ,
использующих
POSIX Threads API
gcc filename.c -lpthread
Размер стека:
обратить внимание
Размер стека потока по умолчанию
зависит от реализации POSIX Threads
API и должен быть настроен по
потребностям приложения с помощью
функций:
pthread_attr_getstacksize (attr, stacksize)
pthread_attr_setstacksize (attr, stacksize)
pthread_attr_getstackaddr (attr, stackaddr)
pthread_attr_setstackaddr (attr, stackaddr)
Источники дополнительных
сведений
• POSIX Threads Programming tutorial
https://computing.llnl.gov/tutorials/pthreads
• International Organization for Standardization, Geneva. Information
technology --- Portable Operating System Interface (POSIX) --- Part
1: System Application Program Interface (API) [C Language],
December 1996.
• The Open Group Base Specifications Issue 6 IEEE Std 1003.1,
2004 Edition. Follow the links.
http://www.opengroup.org/onlinepubs/009695399/mindex.html
• Потоки в UNIX.
http://www.opengroup.org/onlinepubs/007908799/xsh/threads.html
• Лабораторная работа
http://ssdonline.sscc.ru/korneev/Lab9/pthreads1.html
• Manual pages. В командной строке UNIX набрать: man <имя
фунции>.
Вопросы?
Download