Нижегородский государственный университет им. Н.И.Лобачевского Факультет Вычислительной математики и кибернетики Операционные системы: аспекты параллелизма Процессы и потоки. Планирование. Синхронизация. Линёв А.В. 2012 Нижний Новгород Тема обсуждения Программисты создают программы Пользователи запускают программы на исполнение Что представляет собой объект исполнения в ОС? Нижний Новгород 2012 Операционные системы: аспекты параллелизма 2 из 127 Объект исполнения Объект, представляющий прикладную программу в состоянии выполнения, включает Адресное пространство, выделенное для выполнения программы Код выполняющейся программы Данные выполняющейся программы Стек и указатель на его вершину (stack pointer, SP) Выделенные ресурсы ОС (открытые файлы, установленные сетевые соединения и т.д.) Программный счетчик (instruction pointer, IP), указывающий на следующую выполняемую инструкцию Текущие значения регистров общего назначения Объект исполнения представлен двумя понятиями: процесс и поток Нижний Новгород 2012 Операционные системы: аспекты параллелизма 3 из 127 Процесс Процесс - абстракция, представляющая программу во время ее выполнения Процессу ОС выделяет ресурсы, необходимые для выполнения программы, например: адресное пространство процесса содержит его программный код, данные и стек (или стеки) файлы используются процессом для чтения входных данных и записи выходных устройства ввода-вывода используются в соответствии с их назначением Процесс – пассивный объект – владелец ресурсов, контейнер для выполнения потоков Нижний Новгород 2012 Операционные системы: аспекты параллелизма 4 из 127 Поток / нить (thread) Поток - абстракция, представляющая последовательное выполнение команд программы, развертывающееся во времени Процесс может иметь несколько потоков потоки совместно используют глобальные и статические переменные (располагаются в регионе данных) динамически распределяемую память (кучу) системные ресурсы, выделенные процессу каждый поток имеет свои собственные программный счетчик (IP) значения регистров локальные переменные (т.е. свой собственный стек) Процесс - совокупность взаимодействующих потоков и выделенных ему ресурсов Нижний Новгород 2012 Операционные системы: аспекты параллелизма 5 из 127 Процесс с одним потоком виртуальное адресное пространство (ВАП) процесса MAX Стек SP пространство адресов Куча Регион данных Регион кода IP MIN Нижний Новгород 2012 Операционные системы: аспекты параллелизма 6 из 127 Процесс с несколькими потоками виртуальное адресное пространство (ВАП) процесса MAX Стек потока 1 Стек потока 2 пространство адресов Стек потока 3 SP потока 1 SP потока 2 SP потока 3 Куча Регион данных Регион кода MIN Нижний Новгород 2012 Операционные системы: аспекты параллелизма IP потока 1 IP потока 2 IP потока 3 7 из 127 Зачем нужны процессы с несколькими потоками? Для параллельной обработки нескольких однотипных запросов (сетевые сервисы) Для разделения исполнительных активностей, параллельно решающих различные задачи обеспечение пользовательского интерфейса математические вычисления фоновая печать … Для создания параллельных программ, эффективно использующих аппаратные ресурсы (например, несколько аппаратно имеющихся ЦП) Для улучшения структуры программы Нижний Новгород 2012 Операционные системы: аспекты параллелизма 8 из 127 Многопоточная программа vs. Взаимодействующие процессы При использовании потоков экономятся ресурсы (все потоки одного процесса пользуются одним набором ресурсов) экономится время (операции создания/уничтожения потока намного менее затратны, чем операции создания/уничтожения процесса) взаимодействие между потоками одного процесса более удобно и эффективно по причине использования общей памяти Нижний Новгород 2012 Операционные системы: аспекты параллелизма 9 из 127 Процессы и потоки Процесс MS-DOS один поток в процессе несколько потоков в процессе Поток Процесс Java Поток Поток один процесс Нижний Новгород 2012 UNIX by design Процесс Процесс Поток Поток WinNT, Linux, Mach, … Процесс Процесс Поток Поток Поток Поток Поток несколько процессов Операционные системы: аспекты параллелизма 10 из 127 Состояния потока Состояния потока в многозадачной ОС… Создание 1 Готов к выполнению 2 5 3 Выполнение 4 Ожидание 6 Завершение Нижний Новгород 2012 Операционные системы: аспекты параллелизма 12 из 127 Состояния потока в многозадачной ОС… Выполнение – состояние работающего потока – обладающего всеми необходимыми ресурсами, в том числе возможностью использования ЦП Готов к выполнению – поток обладает всеми необходимыми для выполнения ресурсами за исключением ресурса "время ЦП" Ожидание (сон, блокировка) – выполнение потока заблокировано до наступления некоторого внешнего события (например, поступления входных данных или освобождения ресурса) Нижний Новгород 2012 Операционные системы: аспекты параллелизма 13 из 127 Состояния потока в многозадачной ОС С 1 2 ГВ 3 В 4 (2,3) - осуществляются ядром операционной системы (планировщиком) (4) - продолжение работы невозможно 5 О 6 З для продолжения работы требуется наступление какого-либо события поток затребовал недоступный в данный момент ресурс поток переводится в состояние ожидания ядром операционной системы во время обработки системного вызова поток заблокирован внешним по отношению к нему вызовом (5) - производится ядром ОС в момент выполнения условия ожидания Нижний Новгород 2012 Операционные системы: аспекты параллелизма 14 из 127 Thread Scheduling States (2000,XP) Init (0) preempt Ready (1) Transition (6) preemption, quantum end Standby (3) Running (2) voluntary switch Waiting (5) wait resolved after kernel stack made pageable Terminate (4) Ready = thread eligible to be scheduled to run Standby = thread is selected to run on CPU Windows Operating System Internals - by David A. Solomon and Mark E. Russinovich with Andreas Polze Нижний Новгород 2012 Операционные системы: аспекты параллелизма 15 из 127 Управление процессами/потоками Управление процессами/потоками Структуры, описывающие процессы и потоки в ядре ОС Операции над процессами и потоками Распределение ресурсов между процессами/потоками время центрального процессора (выделяется потокам) оперативная память (выделяется процессам) другие ресурсы (как правило, выделяются процессам) Интерфейс прикладных программ (частные реализации) Нижний Новгород 2012 Операционные системы: аспекты параллелизма 17 из 127 Контекст процесса Контекст – множество информации, полностью описывающее состояние объекта (в частности, достаточное для восстановления объекта в случае его удаления) Контекст процесса включает Множество информации, используемое операционной системой для управления ресурсом типа «процесс» Адресное пространство процесса Структуру и содержимое пользовательской части адресного пространства процесса Множество ресурсов, используемых процессом или принадлежащих процессу, и их состояния Нижний Новгород 2012 Операционные системы: аспекты параллелизма 18 из 127 Контекст потока Контекст потока включает Множество информации, используемое операционной системой для управления ресурсом типа «поток» Множество ресурсов, используемых потоком или принадлежащих потоку и их состояния Аппаратный контекст исполнения потока Нижний Новгород 2012 Операционные системы: аспекты параллелизма 19 из 127 Аппаратный контекст потока Состояние процессора с точки зрения предоставляемых потоку прав его использования в конкретной ОС (обычно представляется множеством доступным потоку регистров процессора и их текущими значениями) Состояние других устройств в случае, если управление ими осуществляется непосредственно на уровне команд программы, а не через интерфейс доступа к устройствам через выполнение системных вызовов ОС Нижний Новгород 2012 Операционные системы: аспекты параллелизма 20 из 127 Переключение контекста Переключение контекста происходит при переходе к исполнению другого потока (возможно, другого процесса) При переключении контекста необходимо сохранить контекст вытесняемого потока если поток, выбранный на исполнение, принадлежит другому процессу – сохранить контекст процесса – владельца вытесняемого потока – загрузить контекст процесса – владельца потока, выбранного на исполнение загрузить контекст потока, выбранного на исполнение Для описания процессов и потоков (в том числе для хранения их контекстов) в ядре ОС вводятся специальные структуры – дескрипторы процесса и потока Нижний Новгород 2012 Операционные системы: аспекты параллелизма 21 из 127 Дескриптор процесса Идентификатор процесса Групповые параметры процесса Параметры, используемые в процессе определения приоритета процесса при конкуренции за какой-либо ресурс Состояние процесса Статистические данные Описание адресного пространства процесса Контекст ввода-вывода Контекст безопасности Текущие системные параметры выполнения Код завершения процесса В Linux дескриптор процесса – структура task_struct (include/linux/sched.h), содержит около 100 полей! Нижний Новгород 2012 Операционные системы: аспекты параллелизма 22 из 127 Дескриптор потока Идентификатор потока Идентификатор процесса – владельца потока Параметры, используемые в процессе определения приоритета потока при конкуренции за какой-либо ресурс Статистические данные потока Аппаратный контекст выполнения потока (программный счетчик, стек и указатель на его вершину, значения регистров) Код завершения потока Нижний Новгород 2012 Операционные системы: аспекты параллелизма 23 из 127 Кто управляет процессами и потоками? За управление процессами всегда отвечает ядро ОС Ядро всегда предоставляет каждому процессу один поток, но не всегда поддерживает многопоточность потоки, непосредственно управляемые ядром ОС, называются потоками ядра Можно реализовать многопоточность в библиотеке пользовательского уровня! Нижний Новгород 2012 Операционные системы: аспекты параллелизма 24 из 127 Потоки ядра vs. пользовательские потоки… Ядро Таблица дескрипторов процессов Процесс1 Поток1 Поток2 Библиотека поддержки исполнения потоков Локальная таблица дескрипторов потоков Подпоток Подпоток … Нижний Новгород 2012 Подпоток Подпоток … Подпоток Подпоток … Таблица дескрипторов потоков ПроцессN Поток1 Поток2 Поток3 Библиотека поддержки исполнения потоков Локальная таблица дескрипторов потоков Подпоток Подпоток … Подпоток Подпоток … Операционные системы: аспекты параллелизма Подпоток Подпоток … 25 из 127 Потоки ядра vs. пользовательские потоки При использовании пользовательских потоков (+) Операции над потоками выполняются без выполнения системных вызовов (в 10-100 раз быстрее, чем при использовании потоков ядра) (+) Можно реализовать собственный алгоритм планирования (-) Ядро ничего не знает о потоках пользовательского уровня и распределяет время ЦП независимо от их количества в процессе (-) Если будет выполнен блокирующий системный вызов (например, вызвана синхронная операция ввода-вывода), в состояние ожидания переводится поток ядра, использовавшийся для обеспечения выполнения нескольких (или всех) пользовательских потоков. Соответственно, выполнение всех этих пользовательских потоков будет заблокировано. Нижний Новгород 2012 Операционные системы: аспекты параллелизма 26 из 127 Операции над процессами и потоками Создание процесса Создать дескриптор процесса и поместить его в таблицу процессов Проинициализировать значения полей общего назначения дескриптора процесса Создать виртуальное адресное пространство (ВАП) процесса и сформировать его структуру Заполнить необходимыми данными ВАП процесса (разместить в нем код, данные и т.д.) Выделить процессу ресурсы, которые он может использовать сразу после создания Оповестить подсистемы, принимающие участие в управлении процессами, о создании нового процесса Создать первичный поток процесса Нижний Новгород 2012 Операционные системы: аспекты параллелизма 28 из 127 Создание процесса Таблица дескрипторов процессов Ядро Таблица дескрипторов потоков 1. Создание дескриптора процесса 2. Создание ВАП процесса 3. Формирование структуры ВАП процесса и его заполнение 4. Выделение ресурсов по умолчанию Куча Регион данных Регион кода Нижний Новгород 2012 Создание первичного потока Операционные системы: аспекты параллелизма 29 из 127 Создание потока Создать дескриптор потока и поместить его в таблицу потоков Проинициализировать значения полей общего назначения дескриптора потока Создать области данных, необходимые для функционирования потока в данной аппаратной архитектуре Инициализировать поле дескриптора «аппаратный контекст выполнения потока» Оповестить подсистемы, принимающие участие в управлении потоками, о создании нового потока Перевести поток в состояние «готов к выполнению» Нижний Новгород 2012 Операционные системы: аспекты параллелизма 30 из 127 Создание потока Таблица дескрипторов процессов Стек Ядро SP IP Куча значения регистров Регион данных Регион кода Нижний Новгород 2012 состояние = "готов к выполнению" Операционные системы: аспекты параллелизма Таблица дескрипторов потоков 1. Создание дескриптора потока 2. Создание стека 3. Инициализация аппаратного контекста 4. Установка состояния потока 31 из 127 Завершение потока Сохранить статистические данные потока и код возврата в его дескрипторе Перевести все ресурсы, принадлежащие потоку, в непротиворечивое и стабильное состояние Освободить все ресурсы, принадлежавшие потоку или использовавшиеся потоком Оповестить подсистемы, принимающие участие в управлении потоками, о завершении потока Установить состояние потока в значение «завершен» Если данный поток является последним активным потоком в процессе – завершить процесс После выполнения всех действий остается дескриптор потока, содержащий его код возврата и статистические данные; момент уничтожения дескриптора зависит от реализации Нижний Новгород 2012 Операционные системы: аспекты параллелизма 32 из 127 Завершение процесса Завершить выполнение всех потоков процесса Сохранить статистические данные процесса и код возврата в его дескрипторе Перевести все ресурсы, принадлежащие процессу, в непротиворечивое и стабильное состояние Освободить все ресурсы, принадлежавшие процессу или использовавшиеся процессом Освободить ВАП и уничтожить его Оповестить подсистемы, принимающие участие в управлении процессами, о завершении процесса Установить состояние процесса в значение «завершен» После выполнения всех действий остается дескриптор процесса, содержащий его код возврата и статистические данные; момент уничтожения дескриптора зависит от реализации Нижний Новгород 2012 Операционные системы: аспекты параллелизма 33 из 127 Создание/завершение процесса – Win32 BOOL CreateProcess( LPCTSTR lpszImageName, LPCTSTR lpszCommandLine, LPSECURITY_ATTRIBUTES lpsaProcess, LPSECURITY_ATTRIBUTES lpsaThread, BOOL fInheritHandles, DWORD fdwCreate, LPVOID lpvEnvironment, LPTSTR lpszCurDir, LPSTARTUPINFO lpsiStartInfo, LPPROCESS_INFORMATION lppiProcInfo); VOID ExitProcess(UINT fuExitCode); BOOL TerminateProcess( HANDLE hProcess, UINT uExitCode ); Описание функций можно найти в MSDN и в работе [2] Нижний Новгород 2012 Операционные системы: аспекты параллелизма 34 из 127 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); CreateProcess( NULL, // No module name (use command line). TEXT("MyChildProcess"),// Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. 0, // No creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi ); // Pointer to PROCESS_INFORMATION structure. // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); Нижний Новгород 2012 Операционные системы: аспекты параллелизма 35 из 127 Создание/завершение потока – Win32 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); VOID ExitThread(DWORD dwExitCode); BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode); Описание функций можно найти в MSDN и в работе [2] Нижний Новгород 2012 Операционные системы: аспекты параллелизма 36 из 127 int GlobalVar = 0; DWORD WINAPI ThreadProc( LPVOID arg ){ *(int*)arg = *(int*)arg + 1; ExitThread(0); } int main(void){ int i; HANDLE Threads[10]; for( i = 0; i < 10; i ++ ){ Threads[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)&GlobalVar, 0, NULL); } for( i = 0; i < 10; i ++ ){ WaitForSingleObject(Threads[i],INFINITE); } return 0; } Нижний Новгород 2012 Операционные системы: аспекты параллелизма 37 из 127 Создание/завершение процесса – UNIX… Создание копии процесса int fork(void); Использование ресурсов процесса для выполнения указанной программы int exec*(char *path, char* argv[], char **env); Завершение процесса void exit(int status); Ожидание завершения процесса-потомка int wait(int *status); Описание функций можно найти в документации UNIX (man или info) и в работе [3] Нижний Новгород 2012 Операционные системы: аспекты параллелизма 38 из 127 Итоги Процессы и потоки – объекты, представляющие программы во время их выполнения Процесс – пассивный объект, владелец ресурсов Поток – активный объект С точки зрения ОС, процессы и потоки – специфичные типы ресурсов, требующие специального управления Нижний Новгород 2012 Операционные системы: аспекты параллелизма 39 из 127 Планирование ЦП Тема обсуждения Потокам для выполнения нужен центральный процессор (ЦП) Если потоков больше, чем процессоров, ОС должна обеспечить возможность поочередного использования процессоров потоками Нижний Новгород 2012 Операционные системы: аспекты параллелизма 41 из 127 Что такое "планирование"? Планирование – распределение времени центрального процессора Процесс Поток Процесс Поток Поток Центральный процессор Поток Поток Поток Процесс Поток Поток Нижний Новгород 2012 Операционные системы: аспекты параллелизма 42 из 127 Что такое "планирование"? Планирование – распределение времени центрального процессора Планирование бывает долгосрочное – принятие решений о запуске и откладывании запуска заданий среднесрочное – принятие решений о временном вытеснении процессов на диск краткосрочное (диспетчеризация) – выбор потока, которому следует предоставить ЦП При реализации планирования используется механизм переключения контекстов процессов и потоков Нижний Новгород 2012 Операционные системы: аспекты параллелизма 43 из 127 График выполнения потока а) Длинные блоки вычислений Ожидание завершения ввода-вывода Короткие блоки вычислений б) Время а) Потоки, ограниченные возможностями ЦП б) Потоки, ограниченные возможностями ввода-вывода Нижний Новгород 2012 Операционные системы: аспекты параллелизма 44 из 127 А если потоков несколько? Для каждого потока можно построить график его выполнения в однозадачной среде Ожидание завершения вводавывода или наступления некоторого события Поток2 Поток1 Время Если имеются 2 потока и 1 центральный процессор, операционная система должна определить последовательность использования центрального процессора потоками Нижний Новгород 2012 Операционные системы: аспекты параллелизма 45 из 127 А если потоков несколько? Завершение состояния ожидания – переход в состояние «готов к исполнению» Поток2 Поток1 Поток в состоянии «готов к исполнению» Время Хорошо ли мы распределили время ЦП между потоками? Нижний Новгород 2012 Операционные системы: аспекты параллелизма 46 из 127 Критерии оценки алгоритмов планирования… Общие критерии Справедливость – всем выделяется равное количество времени ЦП Баланс – обеспечение загрузки всех устройств системы Накладные расходы – процент ресурсов, потребляемых планировщиком Масштабируемость – увеличение потребления ресурсов планировщиком при увеличении числа объектов планирования Нижний Новгород 2012 Операционные системы: аспекты параллелизма 47 из 127 Критерии оценки алгоритмов планирования… Справедливость – всем выделяется равное количество времени ЦП Как измерить справедливость? Одинаковое время потребления ЦП? Одинаковое количество выполненных команд? Честно на уровне потоков? процессов? пользователей? Что если один процесс ограничен возможностями ЦП, а другой – возможностями ввода-вывода? Иногда нужно быть несправедливым и явно оказывать предпочтение некоторым определенным классам потоков/запросов/событий (иметь систему приоритетов), но… следует избегать голодания (starvation) – ситуации, когда некоторым потокам процессор может не выделяться в течении неограниченного времени Нижний Новгород 2012 Операционные системы: аспекты параллелизма 48 из 127 Критерии оценки алгоритмов планирования… Системы пакетной обработки данных Пропускная способность – среднее число заданий, полностью выполняемых в единицу времени (час, сутки,…) Оборотное время – среднее время между запуском задания и завершением его обработки Эффективность – средний процент загрузки центрального процессора Нижний Новгород 2012 Операционные системы: аспекты параллелизма 49 из 127 Критерии оценки алгоритмов планирования… Интерактивные системы Время отклика – среднее время между возникновением события и завершением его обработки Время ожидания – среднее время между переходом потока из состояния "ожидание" в состояние "готов к выполнению" и предоставлением ему ЦП Соразмерность – соответствие производительности ожиданиям пользователя Нижний Новгород 2012 Операционные системы: аспекты параллелизма 50 из 127 Критерии оценки алгоритмов планирования Операционные системы реального времени (Окончание обслуживания к сроку) Предсказуемость – соблюдение временных ограничений при выполнении некоторого заранее оговоренного множества системных вызовов Нижний Новгород 2012 Операционные системы: аспекты параллелизма 51 из 127 Моменты планирования Создание нового процесса Создание нового потока Завершение потока или процесса Блокирование потока (переход из состояния "выполнение" в состояние "ожидание") Разблокирование потока (переход из состояния "ожидание" в состояние "готов к выполнению") Срабатывание таймера Нижний Новгород 2012 Операционные системы: аспекты параллелизма 52 из 127 Невытесняющие алгоритмы планирования… Выбирают поток, передают ему центральный процессор и позволяют работать вплоть до блокировки либо до того момента, когда поток сам отдаст центральный процессор Нижний Новгород 2012 Операционные системы: аспекты параллелизма 53 из 127 Невытесняющие алгоритмы планирования Потоки TID=99 TID=10 TID=5 TID=1 Время ЦП Нижний Новгород 2012 Операционные системы: аспекты параллелизма 54 из 127 Вытесняющие алгоритмы планирования… Выбирают поток и позволяют ему работать некоторое максимально возможное фиксированное время. Если к концу заданного интервала времени поток все еще работает, он приостанавливается, и управление переходит к другому потоку (если существует поток, готовый к исполнению). Вытесняющее планирование требует прерываний по таймеру, происходящих в конце отведенного периода времени. При отсутствии таймера возможна реализация только невытесняющих алгоритмов. Нижний Новгород 2012 Операционные системы: аспекты параллелизма 55 из 127 Вытесняющие алгоритмы планирования… Потоки TID=99 TID=10 TID=5 TID=1 Все верно? Нижний Новгород 2012 Операционные системы: аспекты параллелизма Время ЦП 56 из 127 Вытесняющие алгоритмы планирования… Потоки TID=99 TID=10 TID=5 TID=1 Часть потоков может не потреблять Время ЦП каждый свой квант полностью Нижний Новгород 2012 Операционные системы: аспекты параллелизма 57 из 127 Вытесняющие алгоритмы планирования на многопроцессорных системах Потоки TID=99 TID=10 TID=5 TID=1 Время ЦП На двухпроцессорной системе одновременно выполняются не более двух потоков Нижний Новгород 2012 Операционные системы: аспекты параллелизма 58 из 127 First Come – First Served (FCFS или FIFO)… Невытесняющий Планировщик поддерживает очередь готовых к выполнению потоков и предоставляет ЦП первому потоку из очереди При переходе в состояние "готов к выполнению" поток помещается в конец очереди Нижний Новгород 2012 Операционные системы: аспекты параллелизма 59 из 127 First Come – First Served (FCFS или FIFO) Список еще не запущенных потоков Список потоков в состоянии «готов к выполнению» B Поток в состоянии выполнения A Нижний Новгород 2012 C Центральный процессор I J D E F G H Потоки в состоянии ожидания Операционные системы: аспекты параллелизма 60 из 127 Round Robin (RR) RR - вытесняющий аналог FCFS Список потоков в состоянии «готов к выполнению» B Поток в состоянии выполнения A Нижний Новгород 2012 C Центральный процессор Операционные системы: аспекты параллелизма D E F G H Потоки в состоянии ожидания 63 из 127 Приоритетное планирование Необходим дифференцированный подход к потокам В системе могут одновременно существовать служебные процессы и процессы, запущенные пользователями Пользователи могут различаться по статусу Нижний Новгород 2012 Операционные системы: аспекты параллелизма 65 из 127 Приоритетное планирование очереди приоритетов самый высокий приоритет Приоритет 4 Приоритет 3 Приоритет 2 Приоритет 1 Нижний Новгород 2012 самый низкий приоритет Операционные системы: аспекты параллелизма 66 из 127 Приоритетное планирование При использовании приоритетного планирования, если в системе всегда готов к выполнению хотя бы один из высокоприоритетных потоков, то потоки с низкими приоритетами никогда не будут выполнены. Поэтому, как правило, используются некоторые модификации этого алгоритма. Нижний Новгород 2012 Операционные системы: аспекты параллелизма 67 из 127 Приоритетное планирование… В модификациях часто разделяют базовый приоритет потока и эффективный приоритет потока Базовый приоритет назначается потоку посредством некоторого системного вызова, например, инициированного выполнением команды пользователя Эффективный приоритет используется планировщиком при выборе потоков на исполнение и может им изменяться в соответствии с реализованным алгоритмом планирования Нижний Новгород 2012 Операционные системы: аспекты параллелизма 68 из 127 Приоритетное планирование Для предотвращения бесконечной работы высокоприоритетных потоков планировщик может уменьшать с каждым тактом таймера эффективный приоритет выполняющегося потока Для предоставления низкоприоритетным потокам центрального процессора планировщик может проверять время, в течение которого поток находился в состоянии готовности к исполнению Возможно адаптивное и динамическое изменение приоритетов адаптивное изменение – коррекция эффективных приоритетов на основании набора правил динамическое изменение – регулярный пересчет эффективных приоритетов на основании значений некоторой совокупности параметров Нижний Новгород 2012 Операционные системы: аспекты параллелизма 69 из 127 Планирование с использованием многоуровневых очередей планирование очереди внутри очереди приоритетов RR Приоритет 4 RR Приоритет 3 FCFS Приоритет 2 RR Приоритет 1 Нижний Новгород 2012 Операционные системы: аспекты параллелизма самый высокий приоритет самый низкий приоритет 70 из 127 Multi-Level Feedback Queue (MLFQ) При использовании многоуровневых очередей с обратной связью поток не постоянно приписан к определенной очереди, а может мигрировать из очереди в очередь в зависимости от своего поведения Нижний Новгород 2012 Операционные системы: аспекты параллелизма 71 из 127 Планирование в Windows… 31 Приоритеты реального времени Относительные приоритеты потоков 16 15 Изменяемые приоритеты 10 Базовый приоритет процесса – 10 (ABOVE_NORMAL) 15 Time Critical 12 11 10 9 8 Highest Above Normal Normal Below Normal Lowest 1 1 0 Idle i Нижний Новгород 2012 Операционные системы: аспекты параллелизма 77 из 127 Планирование в Windows Размер кванта Эффективный приоритет потока Приоритет потока уменьшился до базового значения Повышение приоритета по окончании ожидания Приоритет потока Снижение приоритета по истечении кванта Вытеснение более приоритетным потоком до истечения кванта Выполнение Ожидание Выполнение Время Нижний Новгород 2012 Операционные системы: аспекты параллелизма 78 из 127 Итоги Существует несколько уровней планирования Существуют различные алгоритмы планирования Определены критерии оценки алгоритмов планирования (зачастую противоположные) В реальных системах реализуются гибридные алгоритмы, использующие, к тому же, адаптивные или динамические приоритеты Нижний Новгород 2012 Операционные системы: аспекты параллелизма 79 из 127 Синхронизация Тема обсуждения При переходе от последовательных решений к параллельным возникает проблема синхронизации обеспечение согласованных действий параллельно работающих модулей при выполнении этапов алгоритма обеспечение целостности используемых данных извещение модулями друг друга о произошедших событиях и т.д. Нижний Новгород 2012 Операционные системы: аспекты параллелизма 81 из 127 Необходимость синхронизации Нижний Новгород 2012 Операционные системы: аспекты параллелизма 82 из 127 Пример многопоточного приложения Пусть есть 2 потока, совместно работающих с общей базой данных. При работе они используют однотипные алгоритмы, включающие следующие три шага: 1. Считать из базы данных в локальный буфер потока запись о клиенте с заданным идентификатором 2. Изменить значение некоторого поля 3. Записать модифицированную запись в базу данных Нижний Новгород 2012 Операционные системы: аспекты параллелизма 83 из 127 Диаграммы выполнения потоков на однопроцессорной системе Поток A(+3) A1 A2 A3 +5 Поток B(+5) B1 Поток A(+3) B2 A1 B3 A2 A3 +3 A2 A3 +8 Поток B(+5) B1 B2 Поток A(+3) B3 A1 Поток B(+5) B1 B2 B3 t Нижний Новгород 2012 Операционные системы: аспекты параллелизма 84 из 127 Диаграммы выполнения потоков на многопроцессорной системе Поток A(+3) A1 A2 A3 +5 Поток B(+5) B1 Поток A(+3) A1 B2 A2 B3 A3 +3 A3 +8 Поток B(+5) B1 B2 Поток A(+3) B3 A1 A2 Поток B(+5) B1 B2 B3 t Нижний Новгород 2012 Операционные системы: аспекты параллелизма 85 из 127 Проблема синхронизации… Результат вычислений в рассмотренном примере не однозначен – все зависит от условий выполнения потоков (разные запуски программы могут привести к разным результатам !!!) Точно такие ситуации могут возникать и при использовании "обычных" общих переменных потоков Нижний Новгород 2012 Операционные системы: аспекты параллелизма 86 из 127 Проблема синхронизации Сложность проблемы синхронизации кроется в нерегулярности возникающих ситуаций – все определяется взаимными скоростями потоков и моментами передачи ЦП от одного потока к другому Ситуация, когда два или более потоков обрабатывают разделяемые данные и конечный результат зависит от соотношения скоростей потоков, называется состязанием или гонками (race conditions) Нижний Новгород 2012 Операционные системы: аспекты параллелизма 87 из 127 Критическая секция… Критическая секция (КС, critical section) – это часть программы, результат выполнения которой может непредсказуемо меняться, если в ходе ее выполнения состояние ресурсов, используемых в этой части программы, изменяется другими потоками Критическая секция всегда определяется по отношению к определенным критическим ресурсам (например, критическим данным), при несогласованном доступе к которым могут возникнуть нежелательные эффекты Нижний Новгород 2012 Операционные системы: аспекты параллелизма 88 из 127 Критическая секция Чтобы исключить эффект гонок по отношению к критическим данным, необходимо обеспечить, чтобы в каждый момент времени в критической секции, связанной с этими данными, находился только один поток. Все остальные потоки должны блокироваться на входе в критическую секцию. Подобное требование обычно называется взаимоисключением (mutual exclusion) Когда один поток покидает критическую секцию, один из ожидающих потоков может в нее войти Нижний Новгород 2012 Операционные системы: аспекты параллелизма 89 из 127 Задача взаимного исключения Постановка задачи Нижний Новгород 2012 Операционные системы: аспекты параллелизма 90 из 127 Задача взаимного исключения. Постановка задачи Необходимо согласовать работу n>1 параллельных потоков при использовании некоторого критического ресурса таким образом, чтобы удовлетворить следующим требованиям одновременно внутри критической секции должно находиться не более одного потока критические секции не должны иметь приоритета в отношении друг друга остановка какого-либо потока вне его критической секции не должна влиять на дальнейшую работу потоков по использованию критического ресурса решение о вхождении потоков в их критические секции при одинаковом времени поступления запросов на такое вхождение и равноприоритетности потоков не откладывается на неопределенный срок, а является конечным во времени относительные скорости развития потоков неизвестны и произвольны любой поток может переходить в любое состояние, отличное от активного, вне пределов своей критической секции освобождение критического ресурса и выход из критической секции должны быть произведены потоком, использующим критический ресурс, за конечное время Нижний Новгород 2012 Операционные системы: аспекты параллелизма 91 из 127 Задача взаимного исключения Аппаратная поддержка решения Нижний Новгород 2012 Операционные системы: аспекты параллелизма 92 из 127 Задача взаимного исключения. Аппаратная поддержка решения Запрещение прерываний Использование разделяемых переменных Алгоритм Деккера Алгоритм Петерсона Алгоритм булочной Использование специальных команд ЦП test-and-set swap read-conditional-write Нижний Новгород 2012 Операционные системы: аспекты параллелизма 93 из 127 Запрещение прерываний while( true ){ DisableInterrupts(); CS(); /* Critical Section */ EnableInterrupts(); NCS(); /* Non-Critical Section */ } Прикладные программы, как правило, не могут запрещать прерывания На многопроцессорных системах прерывания запрещаются только на текущем процессоре, соответственно, несколько ЦП одновременно могут выполнять критическую секцию При запрещении прерываний на длительное время могут возникнуть сложности с функционированием устройств, не получавших должного внимания Нижний Новгород 2012 Операционные системы: аспекты параллелизма 94 из 127 Использование разделяемых переменных – способ №1 bool flag = false; while( true ){ 1 while( flag ) ; 5 flag = true; 6 CS1(); flag = false; NCS1(); } while( true ){ 2 while( flag ) ; 3 flag = true; 4 CS2(); flag = false; Неверное NCS2(); решение } Два потока могут одновременно находиться в критической секции – не удовлетворяется требование взаимоисключения Нижний Новгород 2012 Операционные системы: аспекты параллелизма 95 из 127 Использование разделяемых переменных – способ №2 bool flag1 = false; bool flag2 = false; while( true ){ 1 while( flag2 ) ; 5 flag1 = true; 6 CS1(); flag1 = false; NCS1(); } while( true ){ 2 while( flag1 ) ; 3 flag2 = true; 4 CS2(); flag2 = false; NCS2(); } Неверное решение Два потока опять могут одновременно находиться в критической секции – снова не удовлетворяется требование взаимоисключения Нижний Новгород 2012 Операционные системы: аспекты параллелизма 96 из 127 Использование разделяемых переменных – способ №3 bool flag1 = false; bool flag2 = false; while( true ){ 1 flag1 = true; 4 while( flag2 ) ; CS1(); flag1 = false; NCS1(); } while( true ){ 2 flag2 = true; 3 while( flag1 ) ; CS2(); flag2 = false; NCS2(); } Неверное решение Потоки могут попасть в бесконечный цикл – не выполняется условие конечности времени принятии решения о входе в КС Нижний Новгород 2012 Операционные системы: аспекты параллелизма 97 из 127 Использование разделяемых переменных – способ №3 bool flag1 = true; bool flag2 = false; while( true ){ while( !flag1 ) ; CS1(); flag1 = false; flag2 = true; NCS1(); } while( true ){ while( !flag2 ) 1 ; CS2(); flag2 = false; flag1 = true; Неверное NCS2(); решение } Не выполняется условие «остановка какого-либо потока вне его критической секции не должна влиять на дальнейшую работу потоков по использованию критического ресурса» Нижний Новгород 2012 Операционные системы: аспекты параллелизма 98 из 127 Использование разделяемых переменных – алгоритм Петерсона /* i – номер потока (0 или 1) */ int ready[2] = {0, 0}; int turn = 0; /* Намерение войти в КС */ /* Приоритетный поток */ while( true ) { ready[i] = 1; turn = 1 - i; while( ready[1-i] && turn == 1-i ) ; CSi(); ready[i] = 0; NCSi(); } Нижний Новгород 2012 Операционные системы: аспекты параллелизма 100 из 127 Использование специальных команд ЦП… Команда Test-and-Set (Проверить и присвоить 1) int Test_and_Set (int *target){ int tmp = *target; *target = 1; return tmp; } Решение задачи взаимного исключения int lock = 0; /* Признак блокировки критических данных */ while( true ) { while( Test_and_Set( &lock ) ) ; CSi(); lock = 0; NCSi(); } Нижний Новгород 2012 Операционные системы: аспекты параллелизма 103 из 127 Использование специальных команд ЦП… Необходим доступ к ресурсу Нет Ресурс свободен? Да Занять ресурс При работе с признаком занятости (блокировки) ресурса поток использует "активное ожидания", то есть крутится в цикле, ожидая освобождения признака блокировки Критическая секция Освободить ресурс Нижний Новгород 2012 Операционные системы: аспекты параллелизма 105 из 127 Использование специальных команд ЦП Недостатки активного ожидания Активное ожидание работает, но оно очень затратно: если какой-то поток находится в состоянии активного ожидания, поток, захвативший признак блокировки, не может продолжать свое исполнение и никакой другой поток тоже не может Активное ожидание используется как база для построения высокоуровневых механизмов Существуют ситуации, когда активное ожидание оправдано Нижний Новгород 2012 Операционные системы: аспекты параллелизма 106 из 127 Итоги Понимание реализации параллельного выполнения потоков – ключевой момент при разработке и отладке параллельных программ При разработке параллельных программ необходимо решать задачу взаимного исключения Можно самостоятельно реализовать низкоуровневый механизм, используя один из существующих алгоритмов Можно использовать механизмы синхронизации, предоставляемые операционной системой Нижний Новгород 2012 Операционные системы: аспекты параллелизма 107 из 127 Высокоуровневые механизмы синхронизации Семафоры Мониторы Синхронные сообщения Мы рассмотрим только семафоры Нижний Новгород 2012 Операционные системы: аспекты параллелизма 108 из 127 Семафоры Нижний Новгород 2012 Операционные системы: аспекты параллелизма 109 из 127 Семафоры Семафоры – примитивы синхронизации более высокого уровня абстракции, чем признаки блокировки; предложены Дийкстрой (Dijkstra) в 1968 г. в качестве компонента операционной системы THE Семафор - это целочисленная неотрицательная переменная, для которой определены 2 операции: P и V P(sem) (wait/down) ожидает выполнения условия sem > 0, затем уменьшает sem на 1 и возвращает управление V(sem) (signal/up) увеличивает sem на 1 Операции P и V выполняются атомарно Нижний Новгород 2012 Операционные системы: аспекты параллелизма 110 из 127 Семафоры – реализация Дийкстры typedef struct{ int value; list<thread> L; } semaphore; P(S){ S.value = S.value - 1; if( S.value < 0 ){ add this thread to S.L; block; } } V(S){ S.value = S.value + 1; if( S.value <= 0 ){ remove a thread T from S.L; wakeup T; } } Нижний Новгород 2012 P () и V() – критические секции, должны выполняться атомарно Операционные системы: аспекты параллелизма 112 из 127 Виды семафоров Двоичный семафор S может принимать значения 0 и 1, инициализируется значением 1 обеспечивает эксклюзивный доступ к ресурсу (например, при работе в критической секции) одновременно может выполняться только один поток Использование Semaphore S = 1; while( true ){ P(S); Использование ресурса V(S); } Нижний Новгород 2012 Операционные системы: аспекты параллелизма 113 из 127 Виды семафоров Счетный семафор S инициализируется значением N (число доступных единиц ресурса) представляет ресурсы, состоящие из нескольких однородных элементов позволяет потокам исполняться, пока есть неиспользуемые элементы Использование Semaphore S1 = N, S2 = 1; while( true ){ P(S1); P(S2); Выбор свободного ресурса V(S2); Использование ресурса P(S2); Освобождение ресурса V(S2); V(S1); } Нижний Новгород 2012 Операционные системы: аспекты параллелизма 114 из 127 Мьютексы Мьютекс – двоичный семафор, обычно используемый для организации согласованного доступа к неделимому общему ресурсу. Мьютекс может принимать значения 1 (свободен) и 0 (занят). Операции над мьютексами acquire(mutex) – уменьшить (занять) мьютекс release(mutex) – увеличить (освободить) мьютекс tryacquire(mutex) – часто реализуемая неблокирующая операция, выполняющая попытку уменьшить (занять) мьютекс Нижний Новгород 2012 Операционные системы: аспекты параллелизма 115 из 127 Мьютексы Мьютексы в конкретных реализациях могут иметь дополнительные свойства Запоминание владельца – освободить мьютекс может только поток, захвативший его Рекурсивность – поток может многократно захватить мьютекс (вызывать aquire()); для освобождения мьютекса поток должен соответствующее число раз вызвать release() Наследование приоритета – поток, захвативший мьютекс, временно наследует максимальный из приоритет потоков, ждущих освобождения данного мьютекса Нижний Новгород 2012 Операционные системы: аспекты параллелизма 116 из 127 Пример №1. Задача "Производитель-Потребитель" Имеется циклический буфер из N элементов Потоки-производители добавляют в него записи (по одной за одну операцию) Потоки-потребители извлекают записи (также по одной за раз) Потоки выполняются параллельно End Нижний Новгород 2012 Start Операционные системы: аспекты параллелизма 117 из 127 Пример №1. Задача "Производитель-Потребитель" Semaphore mutex = 1; // семафор, управляющий доступом к разделяемым данным Semaphore empty = n; // количество пустых записей (после запуска все записи пусты) Semaphore full = 0; // количество заполненных записей // (после запуска нет заполненных записей) Producer: P(empty); // ждем появления свободной записи P(mutex); // получаем доступ к указателям (критические данные) <записываем значение в запись> V(mutex); // завершили работу с указателями V(full); // сигнализируем о появлении заполненной записи Consumer: P(full); // ждем появления заполненной записи P(mutex); // получаем доступ к указателям (критические данные) <извлекаем данные из записи> V(mutex); // завершили работу с указателями V(empty); // сигнализируем о появлении свободной записи <используем данные из записи> Нижний Новгород 2012 Операционные системы: аспекты параллелизма 118 из 127 Пример №2. Задача "Читатели-писатели" Имеются критические данные, над которыми определены операции чтения и записи Потоки-писатели изменяют данные; если поток-писатель работает с данными, они не могут использоваться другими потокам Потоки-читатели не изменяют данные; если поток-читатель работает с данными, они могут быть использованы другими потоками-читателями Потоки выполняются параллельно Data Нижний Новгород 2012 Операционные системы: аспекты параллелизма 119 из 127 Пример №2. Задача "Читатели-писатели" Semaphore RC = 1; // управляет доступом к переменной ReadCount Semaphore Access = 1; // управляет допуском к данным писателя или 1-го читателя int ReadCount = 0; // количество "активных" (читающих) читателей Writer: P(Access); // захватываем доступ к критическим данным <выполняем операцию записи> V(Access); // освобождаем доступ к критическим данным Reader: P(RC); // получаем эксклюзивный доступ к переменной ReadCount ReadСount++; // увеличиваем число активных читателей if( ReadСount == 1 ) P(Access); // если мы первые - захватываем доступ к критическим данным V(RC); // освобождаем доступ к переменной ReadCount <выполняем операцию чтения> P(RC); // получаем эксклюзивный доступ к переменной ReadCount ReadСount--; // уменьшаем число активных читателей if( ReadСount == 0 ) V(Access); // если мы последние - освобождаем доступ к критическим данным V(RC); // освобождаем доступ к переменной ReadCount Нижний Новгород 2012 Операционные системы: аспекты параллелизма 120 из 127 Пример №2. Задача "Читатели-писатели" Замечания Первый появившийся читатель переходит в состояние ожидания при выполнении P(Access) в присутствии писателя; все остальные читатели переходят в состояние ожидания при выполнении вызова P(RC) Если при завершении работы писателем или читателем уже присутствуют ожидающие писатели и читатели, выбор потока, захватывающего семафор, определяется реализацией семафора Если потоки-читатели постоянно входят в критическую секцию, возможна задержка ("голодание", starvation) потоков-писателей Нижний Новгород 2012 Операционные системы: аспекты параллелизма 121 из 127 Реализация мьютексов – Win32… Атрибуты мьютекса в Win32 Идентификатор потока – определяет, какой поток захватил мьютекс Счетчик рекурсии - сколько раз была выполнена операция захвата Создание мьютекса HANDLE CreateMutex( PSECURITY_ATTRIBUTES psa, BOOL fInitialOwner, PCTSTR pszName); Открытие существующего мьютекса HANDLE OpenMutex( DWORD fdwAccess, BOOL bInheritHandle, PCTSTR pszName); Закрытие мьютекса BOOL CloseHandle(HANDLE hMutex); Нижний Новгород 2012 Операционные системы: аспекты параллелизма 122 из 127 Реализация мьютексов – Win32 Уменьшение значения мьютекса (Захват мьютекса) DWORD WaitForSingleObject( HANDLE hObject, DWORD dwMilliseconds); DWORD WaitForMultipleObjects( DWORD dwCount, CONST HANDLE* phObjects, BOOL fWaitAll, DWORD dwMilliseconds); Освобождение мьютекса BOOL ReleaseMutex(HANDLE hMutex); Нижний Новгород 2012 Операционные системы: аспекты параллелизма 123 из 127 Реализация семафоров – Win32… Атрибуты семафора в Win32 максимальное число ресурсов (контролируемых семафором) текущее число ресурсов Создание семафора HANDLE CreateSemaphore( PSECURITY_ATTRIBUTE psa, LONG lInitialCount, LONG lMaximumCount, PCTRTR pszName); Открытие существующего семафора HANDLE OpenSemaphore( DWORD fdwAccess, BOOL bInheritHandle, PCTSTR pszName); Закрытие семафора BOOL CloseHandle(HANDLE hMutex); Нижний Новгород 2012 Операционные системы: аспекты параллелизма 124 из 127 Реализация семафоров – Win32 Уменьшение значения семафора DWORD WaitForSingleObject( HANDLE hObject, DWORD dwMilliseconds); DWORD WaitForMultipleObjects( DWORD dwCount, CONST HANDLE* phObjects, BOOL fWaitAll, DWORD dwMilliseconds); Увеличение значения семафора BOOL ReleaseSemaphore( HANDLE hSem, LONG lReleaseCount, PLONG plPreviousCount); Нижний Новгород 2012 Операционные системы: аспекты параллелизма 125 из 127 Итоги С помощью семафоров можно решить любую классическую задачу синхронизации, но по сути, семафоры - это разделяемые глобальные переменные (что является признаком плохой структуры программы) Семафоры используются как для решения задачи взаимного исключения, так и для координации действий Отсутствует связь между семафором и данными, доступом к которым он управляет Нет контроля использования семафоров со стороны компилятора или операционной системы, соответственно - нет гарантий, что семафоры будут использованы правильно Нижний Новгород 2012 Операционные системы: аспекты параллелизма 126 из 127 Литература 1. 2. 3. Таненбаум Э. Современные операционные системы. 2-е изд. - СПб.: Питер, 2002. Карпов В.Е., Коньков К.А. Введение в операционные системы. Курс лекций. 2-е изд. - М.: ИНТУИТ.РУ, 2005. Рихтер Дж. Windows для профессионалов (Создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows). 4-е изд. – М.: Русская Редакция; пер. с англ. – СПб.: Питер, 2001. Нижний Новгород 2012 Операционные системы: аспекты параллелизма 127 из 127