- •Учбово - методичні матеріали Основна література
- •Додаткова література
- •Методичні вказівки
- •Методичні вказівки до виконання лабораторних робіт
- •Лабораторна робота №1
- •1.2. Кешування даних
- •1.2.2. Принцип дії кеш-пам'яті
- •1.3. Вступ до мови програмування Java
- •1.3.1. Виконання Java-програми
- •1.3.2. Що таке jdk
- •1.3.3. Як використовувати jdk
- •1.3.4. Проста програма на Java
- •1.4. Завдання до лабораторної роботи
- •Лабораторна робота № 2
- •2. Створення програм моделювання кількох процесів, що конкурують за спільні ресурси
- •2.1. Понятие процесса
- •2.2. Понятие ресурса
- •2.3. Модель процесса
- •2.4. Создание процесса
- •2.5. Завершение процесса
- •2.6. Состояние процессов
- •2.7. Описание процессов
- •2.8. Управляющие структуры ос
- •2.9. Структуры управления процессами
- •2.9.1. Местоположение процесса
- •2.9.2. Атрибуты процессов
- •Идентификация процессов
- •Информация о состоянии процесса
- •Управляющая информация процесса
- •2.10. Управление процессами
- •2.11. Потоки. Симметричная многопроцессорная обработка
- •2.11.1. Понятие потока
- •2.11.2. Модель потока
- •2.11.3. Использование потоков
- •2.12. Потоки на уровне пользователя и на уровне ядра
- •2.12.1. Потоки на уровне пользователя (ult)
- •2.12.2. Потоки на уровне ядра (klt)
- •2.12.3. Комбинированные подходы
- •2.12.4. Всплывающие потоки
- •Многозадачность в Java. Учебный пример создания и запуска потоков в Java, часть 1
- •Вопросы для самопроверки
- •2.14. Принципы параллельных вычислений
- •2.14.1. Участие операционной системы
- •2.14.2. Взаимодействие процессов
- •2.14.3. Требования к взаимным исключениям
- •2.14.4. Многозадачность в Java. Учебный пример Производитель-Потребитель, часть 2
- •Результаты выполнения программы, 1-й вариант
- •Результаты выполнения программы, 2-й вариант
- •Результаты выполнения программы, 3-й вариант
- •Вопросы для самопроверки
- •2.15. Взаимоисключения: программный подход
- •2.15.1. Алгоритм Деккера
- •2.15.2. Алгоритм Петерсона
- •2.16. Семафоры
- •2.17. Взаимные исключения
- •Листинг 2.8. Взаимоисключения с использованием семафоров
- •2.18. Задача “Производителя-Потребителя” ("Писатель-Читатель")
- •2.19. Мониторы
- •2.19.1. Мониторы с сигналами (мониторы Хоара)
- •2.19.2. Мониторы с оповещением и широковещанием
- •2.19.3. Многозадачность в Java. Учебный пример Производитель-Потребитель, часть 3
- •Результаты выполнения программы, 1-й вариант
- •Результаты выполнения программы, 2-й вариант
- •Вопросы для самопроверки
- •2.20. Завдання на виконання роботи
- •Таб. 2.1. Варіанти завдань
- •Лабораторна робота № 3
- •3. Створення програм моделювання кількох процесів-виробників та процесів-споживачів, що обмінюються інформацією через буферний пул
- •3.1. Теоретичні відомості
- •3.2. Завдання на виконання роботи
- •Лабораторна робота № 4
- •4. Моделювання процесів, що конкурують за спільні ресурси з використанням методів планування
- •4.1. Призупинені процеси
- •4.2. Завдання на виконання роботи
- •Лабораторна робота № 5
- •5. Моделювання Управління процесами та потоками в ос linux Мета роботи. Засвоєння методу планування процесів ос linux, основаному на керуванні пріоритетами та їхнього моделювання засобами мови java.
- •5.1. Процеси у linux
- •5.2. Потоки у linux
- •5.3. Завдання на виконання роботи
Вопросы для самопроверки
Зачем программисты присваивают имена потокам Java?
Каким образом язык Java позволяет программистам создавать потоки из объектов, не являющихся расширением объекта Thread?
Почему при запуске задания на экран выводятся сообщения в различном порядке?
Ответы
Присвоение имен облегчает идентификацию отдельных потоков во время отладки.
В классе может быть реализован интерфейс Runnable, позволяющий объектам класса контролировать жизненный цикл потоков с помощью метода run.
2.14. Принципы параллельных вычислений
В однопроцессорной многозадачной системе процессы выполняются поочередно для создания иллюзии одновременного выполнения. Несмотря на то, что при этом не достигается реальная параллельная работа процессов и, более того, имеются определенные накладные расходы, связанные с переключением между процессами, такое чередующееся выполнение обеспечивает немалые выгоды с точки зрения эффективности и структуризации программ. В многопроцессорных системах возможно не только чередование процессов, но их перекрытие. Перекрытие и чередование процессов представляют собой принципиально разные режимы работы, но их можно рассматривать как примеры параллельных вычислений, которые порождают одинаковые проблемы.
2.14.1. Участие операционной системы
При наличии параллельных вычислений перечислим такие вопросы, которые возникают при создании и управлении ОС.
1. ОС должна отслеживать разные активные процессы. Это выполняется с помощью блоков управления процессов.
2. ОС должна распределять и освобождать разные ресурсы для каждого активного процесса, а именно:
- Процессорное время: это функция планирования;
- Память: большинство ОС используют схему виртуальной памяти;
- Файловая система;
- Устройства ввода-вывода.
3. ОС должна защищать данные и ресурсы каждого процесса от неумышленного влияния других процессов.
4. Результат работы процесса не должен зависеть от скорости его выполнения по отношению к другим процессам, которые выполняются параллельно.
2.14.2. Взаимодействие процессов
При необходимости использовать один и тот же ресурс параллельные процессы вступают в конфликт друг с другом. В частности, если два процесса желают получить доступ до одного ресурса, то ОС выделит этот ресурс одному з процессов, тогда как второй процесс вынужден ожидать на завершение работы с ресурсом первого. Таким образом, скорость работы процесса, которому отказано в немедленном доступе к ресурсу, уменьшается.
Представим такую ситуацию, что при банковской организации системы для обслуживания клиентов выделяют отдельный поток для каждого клиента. Допустим, что добавление данных на вклад клиента сводится к увеличению глобальной переменной Total_Amount.
Рассмотрим случай, когда два клиента А и В совместно пользуются одним и тем же счетом. Пусть на счете было 100 грн. Клиент А хочет добавить до счета 200 грн, а клиент В – 100 грн. Поток ТА соответствует клиенту А, а ТВ – клиенту В.
Рассмотрим такую последовательность операций (Вариант 1).
Поток ТА считывает Total_Amount, равный 100.
Поток ТВ считывает Total_Amount, равный 100.
Поток ТА увеличивает Total_Amount на 200 и сохраняет его в глобальной памяти (Total_Amount, равный 300).
Поток ТВ увеличивает Total_Amount на 100 и сохраняет его в глобальной памяти. В результате в Total_Amount будет 200 грн, вместо 400 грн.
Теперь рассмотрим другую последовательность операций (Вариант 2).
Поток ТА считывает Total_Amount, равный 100, увеличивает его на 200 и записывает в глобальную память.
Поток ТВ считывает Total_Amount, уже равную 300, увеличивает его на 100 и записывает в глобальную память.
В результате оба взноса зарегистрированы успешно.
Как видим, результат выполнения потоков зависит от последовательности выполнения операций потоков в системе. Все это приводит к тому, что в одной ситуации код может выполняться правильно, а в другой нет. Такие ситуации, в которых два (и более) процесса считывают или записывают данные одновременно, и конечный результат зависит от того, какой из них был первым, называют состоянием гонок, или соревнований (race condition), или состязаний.
Попытки решения подобных проблем вызвали необходимость синхронизации процессов. То есть, основное назначение синхронизации – это необходимость обеспечения защиты данных от влияния других потоков.
В случае конкуренции процессов возникают такие три проблемы.
Первая - необходимость взаимных исключений. Предположим, что два или несколько процесса требуют доступ до одного ресурса (ввода-вывода). При выполнении каждый процесс посылает команды в устройство ввода-вывода, получает информацию о его состоянии, посылает и/или получат данные. Мы будем говорить о таком ресурсе как о критическом ресурсе, а о части программы, которая его использует, - как о критическом разделе (секции, critical section) программы. Крайне важно, чтобы в критической секции, связанной с этим ресурсом, в любой момент времени мог находиться только один процесс. Этот прием называют взаимным исключением или блокированием.
В случае блокирования проверяют, не было ли оно уже сделано другими процессами (потоками), а если это так, то этот процесс переходит в ожидание, иначе он совершает блокирование состояния и входит в критическую секцию. После выхода из критической секции процесс снимает блокирование. Так реализуется взаимное исключение, отсюда походит еще одно название блокирования – мьютекс (mutex, сокращение от mutual exclusion). В общем случае мьютексом называют синхронизационный примитив, который не допускает выполнения некоторого фрагмента кода больше как одним процессом. Обычно мьютекс - это переменная, которая может находиться в одном из двух состояний: блокированном или неблокированном – 0 означает неблокированное состояние, а все остальные значения соответствуют блокированному состоянию. Мьютекс можно рассматривать как упрощенный семафор, который мы будем рассматривать позже.
Отсюда следует, что решение проблемы состязаний является преобразованием кода в атомарную операцию.
При реализации взаимных исключений возникают дополнительно две проблемы. Одна из них - взаимное блокирование. Рассмотрим два процесса Р1 и Р2 и два ресурса R1 и R2. Предположим, что каждому процессу для выполнения некоторых функций нужен доступ к обоим ресурсам. При этом возможная ситуация: ОС выделяет ресурс R1 процессу Р2, а ресурс R2 – процессу Р1. Процессы будут взаимно заблокированы.
Последняя проблема – голодание. Предположим, что мы имеем три процесса Р1, Р2, Р3, каждому из которых нужный доступ к ресурсу R. Предположим Р1 удерживает ресурс R, а Р2 и Р3 приостановленные в ожидании освобождения ресурса. После выхода Р1 из критического раздела доступ к ресурсу получает Р2 или Р3. Предположим ОС предоставила доступ к ресурсу R процессу Р3. Пока он работает с ресурсом, доступ к ресурсу вновь требуется процессу Р1. В результате может произойти, что ОС предоставит R снова процессу Р1. Потом доступ может снова понадобиться Р3. Таким образом, возможная ситуация, когда процесс Р2 никогда не получит ресурс R.
Управление конкуренцией неизбежно приводит к участию ОС в этом процессе, поскольку именно она распределяет ресурсы. Кроме того, процессам необходима возможность запрашивать взаимоисключение, такое, как блокировка ресурса перед его использованием. Любое решение этого вопроса требует поддержки ОС, например, такой, как обеспечение возможности блокировки.
Для устранения таких ситуаций может быть использован так называемый аппарат событий. С помощью этого средства могут решаться не только проблемы взаимного исключения, но и более общие задачи синхронизации процессов. В разных ОС аппарат событий реализуется по-своему, но в любом случае используются системные функции аналогичного назначения, которые условно назовем WAIT(x) и POST(x), где x - идентификатор некоторого события. На рисунке 2.7 показан фрагмент обобщенного алгоритма процесса, использующего эти функции.
Рис. 2.7. Реализация критической секции с использованием системных функций WAIT(D) и POST(D)
Если ресурс занят, то процесс не выполняет циклический опрос, а вызывает системную функцию WAIT(D), здесь D обозначает событие, заключающееся в освобождении ресурса D. Функция WAIT(D) переводит активный процесс в состояние ОЖИДАНИЕ и делает отметку в его дескрипторе о том, что процесс ожидает события D. Процесс, который в это время использует ресурс D, после выхода из критической секции выполняет системную функцию POST(D), в результате чего операционная система просматривает очередь ожидающих процессов и переводит процесс, ожидающий события D, в состояние ГОТОВНОСТЬ.
