Какие операции замедляют работу компьютера в многозадачных системах
Существует несколько схем классификации операционных систем . Ниже приведена классификация по некоторым признакам с точки зрения пользователя.
Реализация многозадачности
По числу одновременно выполняемых задач операционные системы можно разделить на два класса:
- многозадачные (Unix, OS/2, Windows);
- однозадачные (например, MS-DOS).
Многозадачная ОС , решая проблемы распределения ресурсов и конкуренции, полностью реализует мультипрограммный режим в соответствии с требованиями раздела "Основные понятия, концепции ОС ".
Многозадачный режим , который воплощает в себе идею разделения времени, называется вытесняющим ( preemptive ). Каждой программе выделяется квант процессорного времени, по истечении которого управление передается другой программе. Говорят, что первая программа будет вытеснена. В вытесняющем режиме работают пользовательские программы большинства коммерческих ОС .
В некоторых ОС (Windows 3.11, например) пользовательская программа может монополизировать процессор , то есть работать в невытесняющем режиме. Как правило, в большинстве систем не подлежит вытеснению код собственно ОС . Ответственные программы, в частности задачи реального времени, также не вытесняются. Более подробно об этом рассказано в лекции, посвященной планированию работы процессора .
По приведенным примерам можно судить о приблизительности классификации. Так, в ОС MS-DOS можно организовать запуск дочерней задачи и наличие в памяти двух и более задач одновременно. Однако эта ОС традиционно считается однозадачной, главным образом из-за отсутствия защитных механизмов и коммуникационных возможностей.
Поддержка многопользовательского режима
По числу одновременно работающих пользователей ОС можно разделить на:
- однопользовательские (MS-DOS, Windows 3.x);
- многопользовательские (Windows NT, Unix).
Наиболее существенное отличие между этими ОС заключается в наличии у многопользовательских систем механизмов защиты персональных данных каждого пользователя.
Многопроцессорная обработка
Вплоть до недавнего времени вычислительные системы имели один центральный процессор . В результате требований к повышению производительности появились многопроцессорные системы , состоящие из двух и более процессоров общего назначения, осуществляющих параллельное выполнение команд. Поддержка мультипроцессирования является важным свойством ОС и приводит к усложнению всех алгоритмов управления ресурсами. Многопроцессорная обработка реализована в таких ОС , как Linux, Solaris, Windows NT, и ряде других.
Многопроцессорные ОС разделяют на симметричные и асимметричные. В симметричных ОС на каждом процессоре функционирует одно и то же ядро, и задача может быть выполнена на любом процессоре , то есть обработка полностью децентрализована . При этом каждому из процессоров доступна вся память.
В асимметричных ОС процессоры неравноправны. Обычно существует главный процессор (master) и подчиненные (slave), загрузку и характер работы которых определяет главный процессор .
Системы реального времени
В разряд многозадачных ОС , наряду с пакетными системами и системами разделения времени , включаются также системы реального времени , не упоминавшиеся до сих пор.
Они используются для управления различными техническими объектами или технологическими процессами. Такие системы характеризуются предельно допустимым временем реакции на внешнее событие, в течение которого должна быть выполнена программа, управляющая объектом. Система должна обрабатывать поступающие данные быстрее, чем они могут поступать, причем от нескольких источников одновременно.
Столь жесткие ограничения сказываются на архитектуре систем реального времени , например, в них может отсутствовать виртуальная память, поддержка которой дает непредсказуемые задержки в выполнении программ. (См. также разделы, связанные с планированием процессов и реализацией виртуальной памяти.)
Приведенная классификация ОС не является исчерпывающей. Более подробно особенности применения современных ОС рассмотрены в [Олифер, 2001].
Золотая середина
Также, сама реализация Erlang/OTP неявно использует разделяемую память. Даже если из питона получится жалкое подобие Erlang — это все равно намного лучше, чем тот безнадежно однозадачный (не путать с зелеными потоками/concurrent IO) интерпретатор питона, который мы имеем сейчас.
Состояние/ячейки данных, используемое для координации, должно быть разделяемым и изменяться строго последовательно. Независимые состояния должны оставаться независимыми, асинхронно выполняющиеся задачи должны выполняться асинхронно. Если лишь часть задач требуют координации, то они и должны разделять некоторую часть состояния для своей координации. Если возможно выполнить одинаковый набор инструкций для большого числа в ячеек в векторе — выполните его при помощи SIMD/CUDA/OpenCL, а не созданием асинхронно выполняющихся потоков, которые потом придется обратно синхронизировать.
Например, оригинальная STM от Нир Шавита использует глобальный атомарный счетчик для координации всех задача, но в остальном "общими" ячейки данных становятся только когда они по-настоящему общие для нескольких задач. Аналогичный подход с общим атомарным счетчиком номера/приоритета транзакции и детальными блокировками также применяет моя реализация STM в виде Python Shared Objects.
5.2 Гонка (race condition)
Недетерминированный порядок исполнения двух путей кода, работающих с одними и теми же данными и исполняемыми в двух различных нитях. Приводит к зависимости порядка и правильности исполнения от случайных факторов.
Устраняется добавлением необходимых блокир овок и примитивов синхронизации . Обычно является легко устраняемым дефектом (забытая блокировка ).
Когда я предложил перевести на русский мою последнюю статью Easy Concurrency with Python Shared Objects на английском, поступило предложение "написать в несколько раз короче и понятнее". Просьба более чем обоснована. Поскольку я уже порядка десяти лет пишу многопоточку и БД, то описываемые мной логические связи выглядели самоочевидно, и я ошибочно расчитывал на аудиторию из трех с половиной человек, которые сидят сейчас где-то в яндексе или гугле. Судя по всему, они там и сидят, но тема им не интересна, поскольку в питоне нет настоящих потоков, а значит для этих людей такого языка программирования не существует. Потому я немножко снижаю планку и делаю общий обзор проблематики параллельных вычислений для людей, которые в них разбираются, но не являются экспертами в области.
Из-за чего весь сыр-бор?
Два процесса выполняются параллельно и независимо. Если мы возьмем первую инструкцию процесса 1, то параллельно с ней может выполниться любая из четырех команд. Вторая команда процесса 1 аналогично не ограничивает выполнение в процессе 2, потому она может выполняться параллельно с любой из четырех команд. Для простоты допускаем, что одна команда атомарна. Всего число возможных сценариев выполнения первого процесса 4^4 = 256. Если в аналогичных первом и втором процессах по десять инструкций, то число различных вариантов выполнения равно 10 10 , то есть, 10 миллиардов. За пару минут мы можем написать 10 миллиардов программ! Вау, мы крутые! А если серьезно, то нам не хватит никакого времени, чтобы отладить все эти 10 миллиардов сценариев выполнения.
По этой причине для успешной реализации параллельных асинхронных задач необходимо беспощадно ограничивать эту параллельность на пересечении задач, в местах согласования и координации.
Структ. многозадачной ОС.doc
Преимущества: возможность полной реализации многозадачного ввода-вывода в ядре ОС, когда ожидание завершения ввода-вывода одной программой позволяет процессору тем временем исполнять другую программу. Сильное повышение надежности системы в целом, в сочетании с использованием защиты памяти — идеал в виде «ни одна программа пользовательского режима не может нарушить работу ОС в целом» становится достижимым хотя бы теоретически, вне вытесняющей многозадачности он не достижим даже в теории. Возможность полного использования многопроцессорных и многоядерных систем.
Недостатки: необходимость особой дисциплины при написании кода, особые требования к его реентрантности, к защите всех разделяемых и глобальных данных объектами типа критических секций и mutex’ов.
Реализована в таких ОС, как:
- VMS
- Linux
- в пользовательском режиме (а часто и в режиме ядра) всех UNIX-подобных ОС , включая версии Mac OS X , iOS ; Symbian OS
- в режиме ядра ОС Windows 3.x — только при исполнении на процессоре 386 или старше, «задачами» являются только все Windows-приложения вместе взятые и каждая отдельная виртуальная машина ДОС, между приложениями Windows вытесняющая многозадачность не использовалась
- Windows 95 / 98 / ME — без полноценной защиты памяти, что служило причиной крайне низкой, на одном уровне с MS-DOS , Windows 3.x и Mac OS версий до X — надежности этих ОС
- Windows NT / 2000 / XP / Vista / 7 и в режиме ядра, и в пользовательском режиме.
- AmigaOS — все версии, до версии 4.0 без полноценной защиты памяти, что на практике для системных программ почти не сказывалось на надёжности из-за высокой стандартизированности, прозрачных API и SDK. Программы ориентированные на «железо» Амиги, наоборот не отличались надёжностью.
5.1 Голодание (starvation)
Задержка времени от пробуждения потока до его вызова на процессор, в течение которой он находится в списке потоков, готовых к исполнению. Возникает по причине присутствия потоков с большими или равными приоритетами, которые исполняются все это время. Негативный эффект заключается в том, что возникает задержка времени от пробуждения потока до исполнения им следующей важной операции, что задерживает исполнение этой операции, а следом за ней и работу многих других компонентов.
Голодание создаёт узкое место в системе и не дает выжать из неё максимальную производительность, ограничиваемую только аппаратно обусловленными узкими местами.
Любое голодание вне 100 % загрузки процессора может быть устранено повышением приоритета голодающей нити, возможно — временным.
Как правило, для предотвращения голодания ОС автоматически вызывает на исполнение готовые к нему низкоприоритетные потоки даже при наличии высокоприоритетных, при условии, что поток не исполнялся в течение долгого времени (~10 секунд). Визуально эта картина хорошо знакома большинству пользователей Windows — если в одной из программ поток зациклился до бесконечности, то переднее окно работает нормально несмотря на это — потоку, связанному с передним окном, Windows повышает приоритет. Остальные же окна перерисовываются с большими задержками, по порции в секунду, ибо их отрисовка в данной ситуации работает только за счет механизма предотвращения голодания (иначе бы голодала вечно).
Заключение
Мы рассмотрели различные взгляды на то, что такое операционная система ; изучили историю развития операционных систем ; выяснили, какие функции обычно выполняют операционные системы ; наконец, разобрались в том, какие существуют подходы к построению операционных систем . Следующую лекцию мы посвятим выяснению понятия "процесс" и вопросам планирования процессов.
Многозада́чность (англ. multitasking) — свойство операционной системы или среды программирования обеспечивать возможность параллельной (или псевдопараллельной) обработки нескольких процессов. Истинная многозадачность операционной системы возможна только в распределённых вычислительных системах.
Содержание
1 Свойства многозадачной среды
2 Трудности реализации многозадачной среды
3 История многозадачных операционных систем
4 Типы псевдопараллельной многозадачности
4.1 Невытесняющая многозадачность
4.2 Совместная или кооперативная многозадачность
4.3 Вытесняющая или приоритетная многозадачность (режим реального времени)
5 Проблемные ситуации в многозадачных системах
5.1 Голодание (starvation)
5.2 Гонка (race condition)
Работа содержит 1 файл
Содержание
СОДЕРЖАНИЕ
На заре вычислений процессорное время было дорогим, а периферийные устройства были очень медленными. Когда компьютер запускал программу, которой требовался доступ к периферийному устройству, центральный процессор (ЦП) должен был бы прекратить выполнение программных инструкций, пока периферийное устройство обрабатывает данные. Обычно это было очень неэффективно.
Первым компьютером, использующим систему мультипрограммирования, был British Leo III, принадлежащий J. Lyons and Co. Во время пакетной обработки в память компьютера было загружено несколько различных программ, и первая из них начала работать. Когда первая программа достигла инструкции, ожидающей периферийного устройства, контекст этой программы сохранялся, а второй программе в памяти давалась возможность выполнить. Процесс продолжался до тех пор, пока все программы не завершили работу. [ необходима цитата ]
Использование мультипрограммирования было усилено появлением виртуальной памяти и технологий виртуальных машин , которые позволили отдельным программам использовать память и ресурсы операционной системы, как если бы другие одновременно выполняющиеся программы были для всех практических целей несуществующими и невидимыми для них. . [ необходима цитата ]
Мультипрограммирование не дает никаких гарантий своевременного выполнения программы. Действительно, первая программа вполне может работать часами без необходимости доступа к периферийным устройствам. Поскольку у интерактивного терминала не было пользователей, ожидавших результатов, это не было проблемой: пользователи передавали колоду перфокарт оператору и возвращались через несколько часов для распечатки результатов. Мультипрограммирование значительно сокращает время ожидания при обработке нескольких пакетов. [3] [4]
Ранние системы многозадачности использовали приложения, которые добровольно уступали время друг другу. Этот подход, который в конечном итоге был поддержан многими компьютерными операционными системами , сегодня известен как совместная многозадачность. Хотя сейчас она редко используется в более крупных системах, за исключением конкретных приложений, таких как CICS или подсистема JES2 , совместная многозадачность когда-то была единственной схемой планирования, используемой Microsoft Windows и Classic Mac OS для одновременного запуска нескольких приложений. Кооперативная многозадачность до сих пор используется в системах RISC OS . [5]
Поскольку кооперативно-многозадачная система полагается на то, что каждый процесс регулярно уступает время другим процессам в системе, одна плохо спроектированная программа может использовать все время ЦП для себя либо путем выполнения обширных вычислений, либо путем активного ожидания ; оба приведут к зависанию всей системы . В серверной среде это опасность, которая делает всю среду неприемлемо хрупкой.
Вытесняющая многозадачность позволяет компьютерной системе более надежно гарантировать каждому процессу регулярный «кусок» рабочего времени. Это также позволяет системе быстро справляться с важными внешними событиями, такими как входящие данные, которые могут потребовать немедленного внимания того или иного процесса. Операционные системы были разработаны для использования преимуществ этих аппаратных возможностей и упреждающего запуска нескольких процессов. Вытесняющая многозадачность была реализована в PDP-6 Monitor и MULTICS в 1964 году, в OS / 360 MFT в 1967 году и в Unix в 1969 году, и была доступна в некоторых операционных системах для таких небольших компьютеров, как PDP-8 DEC; это ключевая особенность всех Unix-подобных операционные системы, такие как Linux , Solaris и BSD с его производными , [6] , а также современные версии Windows.
В любое конкретное время процессы можно сгруппировать в две категории: те, которые ожидают ввода или вывода (так называемые « привязки ввода-вывода »), и те, которые полностью используют ЦП (« привязанные к ЦП »). В примитивных системах программное обеспечение часто « опрашивает » или « занято », ожидая запрошенного ввода (такого как ввод с диска, клавиатуры или сети). В это время система не выполняла полезную работу. С появлением прерываний и вытесняющей многозадачности процессы, связанные с вводом-выводом, могли быть «заблокированы» или приостановлены в ожидании поступления необходимых данных, позволяя другим процессам использовать ЦП. Поскольку поступление запрошенных данных вызовет прерывание,заблокированным процессам может быть гарантирован своевременный возврат к выполнению. [ необходима цитата ]
Самой ранней операционной системой с вытесняющей многозадачностью, доступной домашним пользователям, была Sinclair QDOS на Sinclair QL , выпущенная в 1984 году, но очень немногие люди купили машину. Amiga от Commodore , выпущенная в следующем году, была первым коммерчески успешным домашним компьютером, в котором использовалась эта технология, а его мультимедийные возможности сделали его явным предком современных многозадачных персональных компьютеров. Microsoft сделала вытесняющую многозадачность основной функцией своей флагманской операционной системы в начале 1990-х годов при разработке Windows NT 3.1, а затем Windows 95 . Позже он был принят на Apple Macintosh в Mac OS X, который, как Unix-подобный Операционная система использует вытесняющую многозадачность для всех собственных приложений.
Похожая модель используется в Windows 9x и семействе Windows NT , где собственные 32-разрядные приложения выполняют многозадачность с вытеснением. [7] 64-разрядные версии Windows для архитектур x86-64 и Itanium больше не поддерживают устаревшие 16-разрядные приложения и, таким образом, обеспечивают вытесняющую многозадачность для всех поддерживаемых приложений.
Другая причина для многозадачности заключалась в проектировании вычислительных систем реального времени , где существует ряд, возможно, не связанных внешних действий, которые необходимо контролировать с помощью однопроцессорной системы. В таких системах иерархическая система прерываний сочетается с установлением приоритетов процессов, чтобы гарантировать, что ключевым действиям будет отведена большая часть доступного времени процесса . [ необходима цитата ]
Поскольку многозадачность значительно повысила производительность компьютеров, программисты начали реализовывать приложения в виде наборов взаимодействующих процессов (например, один процесс собирает входные данные, один процесс обрабатывает входные данные, один процесс записывает результаты на диск). Однако для этого потребовались некоторые инструменты, позволяющие процессам эффективно обмениваться данными. [ необходима цитата ]
Потоки возникли из идеи, что наиболее эффективным способом взаимодействия процессов для обмена данными было бы совместное использование всего пространства их памяти. Таким образом, потоки - это фактически процессы, которые выполняются в одном контексте памяти и совместно используют другие ресурсы со своими родительскими процессами , например, открытые файлы. Потоки описываются как легковесные процессы, поскольку переключение между потоками не требует изменения контекста памяти. [8] [9] [10]
Хотя потоки планируются с упреждением, некоторые операционные системы предоставляют вариант потоков, называемых волокнами , которые планируются совместно. В операционных системах, которые не предоставляют волокна, приложение может реализовать свои собственные волокна, используя повторяющиеся вызовы рабочих функций. Волокна даже более легкие, чем потоки, и их несколько легче программировать, хотя они, как правило, теряют некоторые или все преимущества потоков на машинах с несколькими процессорами . [11]
Некоторые системы напрямую поддерживают многопоточность аппаратно .
Для любой многозадачной системы необходимо безопасное и эффективное совместное использование доступа к системным ресурсам. Доступ к памяти должен строго контролироваться, чтобы гарантировать, что ни один процесс не может случайно или намеренно прочитать или записать в области памяти за пределами адресного пространства процесса. Это делается с целью общей стабильности системы и целостности данных, а также безопасности данных.
В хорошо спроектированной и правильно реализованной многозадачной системе данный процесс никогда не может напрямую обращаться к памяти, принадлежащей другому процессу. Исключением из этого правила является общая память; например, в механизме межпроцессного взаимодействия System V ядро выделяет память для совместного использования несколькими процессами. Такие функции часто используются программным обеспечением для управления базами данных, например PostgreSQL.
Неадекватные механизмы защиты памяти либо из-за недостатков в их конструкции, либо из-за плохой реализации допускают уязвимости системы безопасности, которые могут быть потенциально использованы вредоносным программным обеспечением.
Использование файла подкачки или раздела подкачки - это способ для операционной системы предоставить больше памяти, чем доступно физически, путем сохранения частей первичной памяти во вторичной памяти . Хотя многозадачность и подкачка памяти - это два совершенно не связанных между собой техники, они очень часто используются вместе, поскольку подкачка памяти позволяет загружать больше задач одновременно. Как правило, многозадачная система позволяет запускать другой процесс, когда выполняющийся процесс достигает точки, в которой ему приходится ждать, пока некоторая часть памяти будет перезагружена из вторичного хранилища. [12]
Полностью независимые процессы не представляют больших проблем для программирования в многозадачной среде. Большая часть сложности в многозадачных системах возникает из-за необходимости разделять ресурсы компьютера между задачами и синхронизировать работу взаимодействующих задач. [ необходима цитата ]
Различные методы одновременных вычислений используются, чтобы избежать потенциальных проблем, вызванных попытками нескольких задач получить доступ к одному и тому же ресурсу. [ необходима цитата ]
Более крупные системы иногда строились с центральным процессором (-ами) и некоторым количеством процессоров ввода-вывода , что-то вроде асимметричной многопроцессорной обработки . [ необходима цитата ]
С годами системы многозадачности совершенствовались. Современные операционные системы обычно включают подробные механизмы для определения приоритетов процессов, в то время как симметричная многопроцессорная обработка привнесла новые сложности и возможности. [13]
Заключение
Мы рассмотрели различные взгляды на то, что такое операционная система ; изучили историю развития операционных систем ; выяснили, какие функции обычно выполняют операционные системы ; наконец, разобрались в том, какие существуют подходы к построению операционных систем . Следующую лекцию мы посвятим выяснению понятия "процесс" и вопросам планирования процессов.
Многозада́чность (англ. multitasking) — свойство операционной системы или среды программирования обеспечивать возможность параллельной (или псевдопараллельной) обработки нескольких процессов. Истинная многозадачность операционной системы возможна только в распределённых вычислительных системах.
Содержание
1 Свойства многозадачной среды
2 Трудности реализации многозадачной среды
3 История многозадачных операционных систем
4 Типы псевдопараллельной многозадачности
4.1 Невытесняющая многозадачность
4.2 Совместная или кооперативная многозадачность
4.3 Вытесняющая или приоритетная многозадачность (режим реального времени)
5 Проблемные ситуации в многозадачных системах
5.1 Голодание (starvation)
5.2 Гонка (race condition)
Работа содержит 1 файл
4 Типы псевдапаралельной многозадачности
2 Трудности реализации многозадачной среды
3 История многозадачных операционных систем
4 Типы псевдопараллельной многозадачности
4.1 Невытесняющая многозадачность
4.2 Совместная или кооперативная многозадачность
4.3 Вытесняющая или приоритетная многозадачность (режим реального времени)
5 Проблемные ситуации в многозадачных системах
5.1 Голодание (starvation)
5.2 Гонка (race condition)
Многозада́чность ( англ. multit asking) — свойство операционной системы или среды программирования обеспечивать возможность параллельной (или псевдопараллельной ) обработки нескольких процессов. Истинная многозадачность операционной системы возможна только в распределённых вычислительных системах .
Существует 2 типа многозадачности:
- Процессная многозадачность (основанная на процессах — одновременно выполняющихся программах). Здесь программа — наименьший элемент кода, которым может управлять планировщик операционной системы. Более известна большинству пользователей (работа в текстовом редакторе и прослушивание музыки).
- Поточная многозадачность (основанная на потоках). Наименьший элемент управляемого кода — поток (одна программа может выполнять 2 и более задачи одновременно).
1 Свойства многозадачной среды
Примитивные многозадачные среды обеспечивают чистое «разделение ресурсов», когда за каждой задачей закрепляется определённый участок памяти, и задача активизируется в строго определённые интервалы времени.
Более развитые многозадачные системы проводят распределение ресурсов динамически, когда задача стартует в памяти или покидает память в зависимости от её приоритета и от стратегии системы. Такая многозадачная среда обладает следующими особенностями:
- Каждая задача имеет свой приоритет, в соответствии с которым получает процессорное время и память
- Система организует очереди задач так, чтобы все задачи получили ресурсы, в зависимости от приоритетов и стратегии системы
- Система организует обработку прерываний , по которым задачи могут активироваться, деактивироваться и удаляться
- По окончании положенного кванта времени ядро временно переводит задачу из состояния выполнения в состояние готовности, отдавая ресурсы другим задачам. При нехватке памяти страницы невыполняющихся задач могут быть вытеснены на диск ( своппинг ), а потом через определённое системой время, восстанавливаться в памяти
- Система обеспечивает защиту адресного пространства задачи от несанкционированного вмешательства других задач
- Система обеспечивает защиту адресного пространства своего ядра от несанкционированного вмешательства задач
- Система распознаёт сбои и зависания отдельных задач и прекращает их
- Система решает конфликты доступа к ресурсам и устройствам, не допуская тупиковых ситуаций общего зависания от ожидания заблокированных ресурсов
- Система гарантирует каждой задаче, что рано или поздно она будет активирована
- Система обрабатывает запросы реального времени
- Система обеспечивает коммуникацию между процессами
2 Трудности реализации многозадачной системы
Основной трудностью реализации многозадачной среды является её надёжность, выраженная в защите памяти, обработке сбоев и прерываний , предохранении от зависаний и тупиковых ситуаций .
Кроме надёжности, многозадачная среда должна быть эффективной. Затраты ресурсов на её поддержание не должны: мешать процессам проходить, замедлять их работу, резко ограничивать память.
3 История многозадачных операционных систем
Поначалу реализация многозадачных операционных систем представляла собой серьёзную техническую трудность, отчего внедрение многозадачных систем затягивалось, а пользователи долгое время после внедрения предпочитали однозадачные.
В дальнейшем, после появления нескольких удачных решений, многозадачные среды стали совершенствоваться, и в настоящее время употребляются повсеместно. Впервые многозадачность операционной системы была реализована в ходе разработки операционной системы Multics ( 1964 год ). Одной из первых многозадачных систем была OS/360 (1966), используемая для компьютеров фирмы IBM и их советских аналогов ЕС ЭВМ . Разработки системы были сильно затянуты, и на начальное время фирма IBM выдвинула однозадачный DOS , чтобы удовлетворить заказчиков до полной сдачи OS/360 в эксплуатацию. Система подвергалась критике по причине малой надёжности и трудности эксплуатации.
В 1969году на основе Multics была разработана система UNIX с достаточно аккуратным алгоритмическим решением проблемы многозадачности. В настоящее время на базе UNIX созданы десятки операционных систем.
На компьютерах PDP-11 и их советских аналогах СМ-4 использовалась многозадачная система RSX-11 (советский аналог — ОСРВ СМ ЭВМ ), и система распределения времени TSX-PLUS, обеспечивающая ограниченные возможности многозадачности и многопользовательский режим разделения времени, эмулируя для каждого пользователя однозадачную RT-11 (советский аналог — РАФОС ). Последнее решение было весьма популярно из-за низкой эффективности и надёжности полноценной многозадачной системы.
Аккуратным решением оказалась операционная система VMS , разработанная первоначально для компьютеров VAX (советский аналог — СМ-1700 ) как развитие RSX-11.
Первый в мире мультимедийный персонал ьный компьютер Amiga 1000 ( 1984 год ) изначально проектировался с расчётом на полную аппаратную поддержку вытесняющей многозадачности реального времени в ОС AmigaOS . В данном случае разработка аппаратной и программной части велась параллельно, это привело к тому, что по показателю квантования планировщика многозадачности (1/50 секунды на переключение контекста) AmigaOS долгое время оставалась непревзойдённой на персональных компьютерах .
Многозадачность обеспечивала также фирма Microsoft в операционных системах Windows . При этом Microsoft выбрала две линии разработок — на базе приобретённой ею Windows 0.9, которая после долгой доработки системы, изначально обладавшей кооперативной многозадачностью, аналогичной Mac OS , вылилась в линейку Windows 3.x, и на основе идей, заложенных в VMS, которые привели к созданию операционных систем Windows NT . Использование опыта VMS обеспечило системам существенно более высокую производительность и надёжность. По времени переключения контекста многозадачности (квантование) только эти операционные системы могут быть сравнимы с AmigaOS и UNIX (а также его потомками, такими, как ядро Linux ).
Интересно, что многозадачность может быть реализована не только в операционной, но и языковой среде. Например, спецификации языков программирования Modula-2 и Ad a требуют поддержки многозадачности вне привязки к какой-либо операционной системе. В результате, популярная в первой половине 1990-х годов реализация языка программирования TopSpeed Модула-2 от JPI / Clario n позволяляла организовывать различные типы многозадачности (кооперативную и вытесняющую — см. ниже) для потоков одной программы в рамках такой принципиально однозадачной операционной системы, как MS-DOS . Это осуществлялось путём включения в модуль программы компактного планировщика задач , содержащего обработчик таймерных прерываний. Языки программирования, обладающие таким свойством, иногда называют языками реального времени .
Что там сложного? Есть конкуренция за ресурс — повесь мьютекс. Я так всегда делаю.
Блокировки, они же семафоры или мьютексы. Если вы только начали осваивать многопоточность в классических императивных языках, то вы знаете про задачу "обедающих философов", и в качестве простейшего решения предложите "официанта", то есть, простую блокировку. Ведь отдельная блокировка на каждую вилку быстро приводит вас к дедлокам.
А еще лучше вообще иметь только одну блокировку на все вилки, ложки, философов, и стол одновременно — создатели питона примерно так и подумали.
Если же вы решили использовать множественные блокировки, то неявные и допускающие вложенность блокировки (Rust std::sync::Mutex или Java synchronized) — путь в никуда, поскольку становится очень легко создать неочевидно дедлочащуюся программу. На самом деле, даже без дедлоков детальные блокировки не являются панацеей, поскольку простые блокировки, они же "семафоры Дейкстры", ограничены в своих способностях:
Хотя задачу курильщиков и возможно решить семафорами Дейкстры, такие "семафоры курильщика" дают сложный в понимании и поддержке алгоритм, при том, что задача, казалось бы, элементарна. Потому вторым по популярности механизмом блокировок стали условные переменные и более общий аспект оных — мониторы (в том числе уже упомянутое Java synchronized). Правда, проблемы дедлоков при множественных блокировках они не решают.
Что же делать? Мы все умрем? Да, но проблему дедлоков можно решить. Одно из остроумных решений для задачи обедающих философов предложил сам Дейкстра — брать детальные блокировки только в одном заранее заданном порядке. Следующий забавный прием — брать блокировки всем скопом одной командой либо отменять взятие блокировки. Такое можно реализовать на любой абстракции с примитивом try-lock (например, compare-and-swap), при помощи бесконечного цикла (например, std::lock из библиотеки C++).
Одна из самых последних и перспективных альтернатив блокировкам — это транзакционная память, по сути атомарный compare-and-swap на большом числе ячеек. Идею транзакционной памяти развил в конкретную программную реализацию, STM, мой любимый автор книг и статей по многопоточности — Нир Шавит. Главное преимущество STM — отсутствие дедлоков. В каком-то смысле транзакционная память достаточно стара, если вспомнить, что реляционные СУБД давно умели в транзакции. Программная транзакционная память, как правило, берет блокировки всем скопом, как в описанном выше алгоритме предварительной блокировки, но делает это не до выполнения операций изменения ячеек памяти, а после — таким образом нам не обязательно до начала работы алгоритма знать список нужных нам блокировок и длительность этих блокировок минимальна. Из популярных готовых решений на эту тему можно вспомнить Clojure и GHC.
У наивной реализации STM есть проблема — при интенсивных конфликтах меж потоками приложение большую часть времени крутит откаты транзакций вхолостую: подробнее.
Решение этой проблемы уже придумано за нас — это алгоритм раннего разрешения конфликтов, при котором реализация не ждет окончания транзакции для того, чтобы осознать невозможность применения ее результатов, а сразу прерывает одну из конфликтующих транзакций. По сути это способ организации детальных блокировок с разрешением дедлоков через откат изменений. Такой подход я и перенял при реализации Python Shared Object.
Коротко: взаимоисключающая блокировка не является основным средством организации доступа к разделяемой памяти и вообще разделяемым ресурсам, но именно этими блокировками чаще всего злоупотребляют.
Подход, известный также как "у меня болит палец — отрежу себе руку!".
Начну издалека. Если мы попытаемся разделить все-все-все алгоритмы и механизмы координации на самые простые винтики и гайки, то получим два основных примитива:
Забавно, что создатель величайшей платформы Erlang для построения распределенных систем, Джо Армстронг, не строит иллюзий и осознает принципиальную неразрешимость проблемы. Вот диаграмма ситуации, которую Армстронг пытался описать на пальцах:
Почему в этот горячий пирожок играют? Потому что идеальное решение невозможно чисто теоретически (FLP-недостижимость) — все практически реализации являются тем или иным компромиссом. Но есть желающие "идеальное решение" купить, потому используется популярный маркетинговый прием: недостатки существующих решений уже хорошо известны, а недостатки нашей новой системы еще не известны… значит можно сказать, что их нет. Так и развиваются многие Big Data проекты.
Когда же у вас есть хотя бы общий атомарный счетчик, а еще лучше — общий атомарный список транзакций, дальше вы можете наращивать объем "нагрузочных данных" как угодно, реплицировать их в eventual consistency хранилищах, придавать им произвольную форму (как это сделало в том же Tango, давшем пользователю свободу выбора формы данных) — это всё имеет второстепенное значение и легко меняется, хотя многие люди по прежнему обращают внимание на обёртку, а не на суть. То есть, ходовые качества машины определяются двигателем, трансмиссией, рулевой системой, но большинство видит лишь красивый кузов и отделку салона, к сожалению. Я хочу здесь подчеркнуть, что ZooKeeper в случае Tango, YandexDB, Calvin, ClickHouse и прочих аналогичных проектов — это не "просто вспомогательная штука", как его рисуют, а ключевой компонент и большая часть сложности реализации всей СУБД, и этот компонент, к тому же, полностью определяет число транзакций в секунду, которые сможет обработать весь кластер.
4.2 Совместная или кооперативная многозадачность
Кооперативную многозадачность можно назвать многозадачностью «второй ступени» поскольку она использует более передовые методы, чем простое переключение задач, реализованное многими известными программами (например, DOS Shell из MS-DOS 5.0 при простом переключении активная программа получает все процессорное время, а фоновые приложения полностью замораживаются. При кооперативной многозадачности приложение может захватить фактически столько процессорного времени, сколько оно считает нужным. Все приложения делят процессорное время, периодически передавая управление следующей задаче.
Преимущества кооперативной многозадачности: отсутствие необходимости защищать все разделяемые структуры данных объектами типа критических секций и mutex’, что упрощает программирование, особенно перенос кода из однозадачных сред в многозадачные.
Недостатки: неспособность всех приложений работать в случае ошибки в одном из них, приводящей к отсутствию вызова операции «отдать процессорное время». Крайне затрудненная возможность реализации многозадачной архитектуры ввода-вывода в ядре ОС, позволяющей процессору исполнять одну задачу в то время, как другая задача инициировала операцию ввода-вывода и ждет её завершения.
Реализована в пользовательском режиме ОС Windows версий до 3.х включительно, Mac OS версий до Mac OS X, а также внутри ядер многих UNIX-подобных ОС , таких, как FreeBSD, а в течение долгого времени — и Linux.
4.3 Вытесняющая или приоритетная многозадачность ( режим реального времени )
Вид многозадачности, в котором операционная система сама передает управление от одной выполняемой программы другой в случае завершения операций ввода-вывода, возникновения событий в аппаратуре компьютера, истечения таймеров и квантов времени, или же поступлений тех или иных сигналов от одной программы к другой. В этом виде многозадачности процессор может быть переключен с исполнения одной программы на исполнение другой без всякого пожелания первой программы и буквально между любыми двумя инструкциями в её коде. Распределение процессорного времени осуществляется планировщиком процессов. К тому же каждой задаче может быть назначен пользователем или самой операционной системой определенный приоритет, что обеспечивает гибкое управление распределением процессорного времени между задачами (например, можно снизить приоритет ресурсоёмкой программе, снизив тем самым скорость её работы, но повысив производительность фоновых процессов). Этот вид многозадачности обеспечивает более быстрый отклик на действия пользователя.
Многозада́чность (англ. multitasking) — свойство операционной системы или среды программирования обеспечивать возможность параллельной (или псевдопараллельной) обработки нескольких процессов. Истинная многозадачность операционной системы возможна только в распределённых вычислительных системах.
Содержание
1 Свойства многозадачной среды
2 Трудности реализации многозадачной среды
3 История многозадачных операционных систем
4 Типы псевдопараллельной многозадачности
4.1 Невытесняющая многозадачность
4.2 Совместная или кооперативная многозадачность
4.3 Вытесняющая или приоритетная многозадачность (режим реального времени)
5 Проблемные ситуации в многозадачных системах
5.1 Голодание (starvation)
5.2 Гонка (race condition)
Работа содержит 1 файл
4.1 Невытесняющая многозадачность
Тип многозадачности, при котором операционная система одновременно загружает в память два или более приложений, но процессорное время предоставляется только основному приложению. Для выполнения фонового приложения оно должно быть активизировано. Подобная многозадачность может быть реализована не только в операционной системе, но и с помощью программ-переключателей задач. В этой категории известна программа DESQview , работавшая под DOS и выпущенная первый раз в 1985 году.
5 Проблемные ситуации в многозадачных системах
Тесты, еще тесты, нужно больше тестов
Как же тестировать и отлаживать многозадачные и распределенные системы? Основная проблема многопоточных, многозадачных, распределенных систем — это недетерминированность их поведения. То есть, ваша система может работать пять лет, а потом резко начать падать из-за какого-то незначительного изменения алгоритма.
В общем случае ответ на вопрос "как тестировать?" — "никак", вы подходите к проблемы с неправильной стороны. Но не расстраивайтесь — это нормально, так делает много кто. По этой причине, например, большинство распределенных СУБД, заявлявших про строгую согласованность данных и отказоустойчивость, в жестких тестах на Jepsen показывают, что на самом деле никогда не обеспечивали как минимум одну из этих гарантий: подробнее.
Тестирование — это способ обнаружить наличие проблемы, но тестированием невозможно доказать отсутствие проблем. Если в качестве отказоустойчивого хранилища согласованных данных вы используете не ZooKeeper и не Etcd, то с большой вероятностью ваша система потеряет/испортит данные или вовсе упадет при потере лидера. Если вы уделите пару часов чтению серии статей по ссылке, то вы узнаете, что какой-нибудь Galera Cluster способен нарушать согласованность даже на полностью исправном кластере, а MongoDB не дает даже "eventual consistency" гарантий при отказах (то есть, в MongoDB ваши данные из подтвержденных транзакций может быть сохранятся, а может быть не сохранятся). Однако, даже если вы построили систему на базе условно надежных ZooKeeper или Etcd, вы не знаете, сколько еще проблем возникло из-за некорректного использования оных в самописном коде.
Единственный более-менее гарантированный способ построить работающую систему — это прежде всего грамотно подойти к ее проектированию и реализации, доказать корректность алгоритма, а не полагаться на популярный нынче метод тестирования и "авось". Вторая линия обороны — это тестирование, но не простое. Разработчики должны понимать, что если ошибка есть, то ее необходимо обнаружить, а не замести под ковер и подпереть костылем. То есть, без участия и сотрудничества самих разработчиков невозможно эффективно произвести тестирование. Необходимо тестировать систему в самых неудобных и опасных режимах, предусмотреть в исходном коде отладочные опции для более частого срабатывания редких фрагментов кода — в том числе такой подход я задействовал для своего проекта Python Shared Objects. В случае отказоустойчивых кластеров обязательно необходимо периодически симулировать отказы, как это делает, например, Яндекс.
Поскольку очень часто проблема происходит только один раз и больше никогда не повторяется, то большую ценность имеет логирование, создание снимков состояния системы во время проблемы. Для последнего, например, есть замечательная утилита rr от Mozilla, которая была разработана специально для отладки многопоточного кода в Firefox. Эта утилита позволяет выполнить код в обратном направлении, точно восстанавливая последовательность выполнения асинхронных потоков, приведшую к ошибке. И хотя облака нынче стали популярным хайпом, выбор инструментов для отладки многозадачного кода и распределенных систем на удивление скудный. Для распределенных систем есть упомянутый Jepsen, для многопоточных есть, например, ThreadSanitizer.
К сожалению, для тестирования моего Python Shared Objects мне так и не удалось найти готового решения для неинтрузивного логирования. Неинтрузивного — поскольку для многопоточного кода имеет место так "эффект наблюдателя" — когда при логировании программа ведет себя совсем не так, как без него. Когда-то давно для закрытой разработки я сам реализовывал неинтрузивное логирование на Delphi, но это было давно и неправда, а на сишные программы этот код довольно плохо налазит.
Коротко: при создании сложных многопоточных, многозадачных, и распределенных систем грамотный подход и такие люди, как я, с большим трудом заменяются тестами и "большой дружной командой".
Современные настольные операционные системы способны одновременно обрабатывать большое количество различных процессов. На этом снимке экрана показано, как Linux Mint одновременно работает с окружением рабочего стола Xfce , Firefox , программой-калькулятором, встроенным календарем, Vim , GIMP и медиаплеером VLC .
Возможности многозадачности Microsoft Windows 1.0 1, выпущенной в 1985 году, здесь показаны программы MS-DOS Executive и Calculator.
В вычислении , многозадачности является одновременное выполнение множества задач (также известный как процессы ) в течение определенного периода времени. Новые задачи могут прерывать уже начатые до их завершения, а не ждать их завершения. В результате компьютер выполняет сегменты множества задач с чередованием, в то время как задачи совместно используют общие ресурсы обработки, такие как центральные процессоры (ЦП) и основная память . Многозадачность автоматически прерывает запущенную программу, сохраняя ее состояние (частичные результаты, содержимое памяти и содержимое регистров компьютера) и загружая сохраненное состояние другой программы и передавая ей управление. Этот " переключатель контекста" «может запускаться через фиксированные интервалы времени ( упреждающая многозадачность ), либо выполняющаяся программа может быть закодирована, чтобы сигнализировать управляющему программному обеспечению, когда она может быть прервана ( совместная многозадачность ).
Многозадачность не требует параллельного выполнения нескольких задач в одно и то же время; вместо этого он позволяет продвигаться более чем одной задаче за определенный период времени. [1] Даже на многопроцессорных компьютерах многозадачность позволяет выполнять гораздо больше задач, чем есть ЦП.
Многозадачность - обычная черта компьютерных операционных систем. Это позволяет более эффективно использовать компьютерное оборудование; если программа ожидает какого-либо внешнего события, такого как ввод пользователя или передача ввода / вывода с периферийным устройством для завершения, центральный процессор все еще может использоваться с другой программой. В системе с разделением времени несколько человек-операторов используют один и тот же процессор, как если бы он был выделен для их использования, в то время как за кулисами компьютер обслуживает множество пользователей, выполняя многозадачность их индивидуальных программ. В многопрограммных системах задача выполняется до тех пор, пока ей не придется ждать внешнего события или пока планировщик операционной системы принудительно не выгружает выполняющуюся задачу из ЦП. В реальном времени системы, подобные тем, которые предназначены для управления промышленными роботами, требуют своевременной обработки; один процессор может использоваться совместно для вычислений движения машины, обмена данными и пользовательского интерфейса. [2]
Часто многозадачные операционные системы включают меры по изменению приоритета отдельных задач, чтобы важные задания получали больше процессорного времени, чем те, которые считаются менее важными. В зависимости от операционной системы задача может быть такой же большой, как вся прикладная программа, или может состоять из более мелких потоков, которые выполняют части общей программы.
Процессор, предназначенный для использования с многозадачными операционными системами, может включать в себя специальное оборудование для безопасной поддержки нескольких задач, таких как защита памяти , и защитные кольца, которые гарантируют, что программное обеспечение надзора не может быть повреждено или нарушено программными ошибками пользовательского режима.
Термин «многозадачность» стал международным, поскольку это слово используется во многих других языках, таких как немецкий, итальянский, голландский, датский и норвежский.
1 Свойства многозадачной среды
Структ. многозадачной ОС.doc
Читайте также: