- Многозадачность
- Что такое многозадачность?
- Как работать в таком режиме?
- Плюсы и минусы
- Резюме
- Национальная библиотека им. Н. Э. Баумана Bauman National Library
- Персональные инструменты
- Многозадачность (Операционные Системы)
- Содержание
- Свойства многозадачной среды
- Трудности реализации многозадачной среды
- История многозадачных операционных систем
- Классификация
- По типу наименьшего элемента управляемого кода
- Процессная многозадачность.
- Поточная многозадачность.
- По способу организации времени выполнения каждого процесса
- Параллельная многозадачность
- Типы псевдопараллельной многозадачности
- Диспетчеризация
- Состояние задачи
- Стратегии диспетчеризации
- Программная реализация многозадачности
- Критические разделы
- Использование событий
- Проблемные ситуации в многозадачных системах
- Голодание (starvation)
- Гонка (race condition)
- Инверсия приоритета
- Процессы в Windows и потоковая многозадачность
- Многозадачность в Linux
- Использование getpid() и getppid()
Многозадачность
Когда в начале 60-х годов прошлого века создали первую операционную систему IBM, пользователей поразила возможность компьютера выполнять несколько функций одновременно. То есть процессор легко переключался с одной задачи на другую, постепенно доводя их все до логического завершения. Впечатлившись таким эффектом, мультизадачность попробовали перенести в сферу человеческой деятельности. Тогда показалось, что умение выполнять несколько дел одновременно – это очень полезный навык, овладев которым можно кратно повысить эффективность в работе при этом сэкономив уйму времени. Так ли это на самом деле? Давайте разбираться.
Что такое многозадачность?
Начнем с определения. Многозадачность – это возможность, умение, навык выполнять несколько процессов одновременно, переключаясь с одной задачи на другую. Изначально термин применялся сугубо в среде программирования, но постепенно перекочевал в производство и в сферу человеческой деятельности.
Скорей всего вы не раз слышали о выдающихся способностях Цезаря делать одновременно два и больше дел. Воодушевившись таким «подвигом», вы «задвинули» усердие в выполнении одного дела на дальнюю полку и попробовали переключаться с одной задачи на другую, потом на третью и так далее. Всего по чуть-чуть и что в итоге?
А на выходе вы получили несколько начатых задач и ни одной завершенной. Вдобавок ко всему вы совершенно запутались, какое дело выполнить в первую очередь, а какое отложить напоследок. И, главное, вы потратили время и ресурсы мозга впустую. Мотивация на нуле, ком незавершенных задач вырос до небес. В итоге минусовая эффективность и стрессовая ситуация. Приехали.
Умение работать в режиме многозадачности – это не такой уж полезный и ценный навык, как кажется на первый взгляд. Исследования показывают, что мультизадачность вредит трудоспособности человека. Мы не роботы к счастью, поэтому продуктивность работы во многом зависит от умения концентрироваться на выполнении одной задачи. Цепочку дел мы выполняем последовательно, завершая одно и приступая к другому. По мере достижения целей растет мотивация и желание добиваться больших успехов, экономится время. Казалось бы, схватившись за два дела сразу, время на выполнение задач должно сократиться наполовину. Но в действительности потребуется вдвое больше усилий и при этом шансы на успешное завершение сократятся.
Например, вам нужно расставить 10 тарелок на столе, полить цветы на подоконнике в 10 вазах и разослать 10 пригласительных SMS. Попробуем включить режим многозадачности – это, значит, делаем все сразу, перепрыгивая с одной задачи на другую. Поставили 3 тарелки, побежали поливать 3 цветочные вазы, а потом или одновременно с поливом отправили 3 SMS. Вернулись к тарелкам, следом вазы и опять сообщения. И так по кругу. Простые задачки, но, выполняя их все сразу, вы устанете сильнее и потратите времени больше. При этом на середине всего действа включатся побочные эффекты многозадачности: вместо того чтобы отправить SMS, вы, зачем-то польете телефон водой или выставите тарелку на подоконник, а не на стол.
А теперь сделайте те же простые задачи последовательно: сначала тарелки, потом поливка и в завершении отправка сообщений. Вы удивитесь – и дела идут быстрее и мозг цел!
Усложним нагрузку, а точнее сделаем приближенной к реальности. Например, вы пишите отчет или презентацию и одновременно проверяете новые сообщения в одноклассниках или ВК, отвечаете на смс или просьбы коллег помочь по «неотложному» делу. В 99% случаев, работая в режиме такой многозадачности, вы заметите, что время утекло непонятно куда, рабочий настрой улетучился, а основной работы сделано всего 10-15%. Шокирующий вывод: чем больше вы отвлекаетесь, тем сложнее сосредоточиться на работе. Гаджеты, аккаунты в соцсетях, email-почта и другое – это пожиратели времени и усилий, которые вы могли бы с куда большей пользой потратить на полезное дело.
Мы сильно преувеличиваем важность коммуникации – эта мысль кажется такой несовременной в нашу эпоху. Но, если вы планируете завершить задачу максимально эффективно и быстро, то отключите все раздражители. Это поможет сосредоточиться на задаче.
Как работать в таком режиме?
Режим многозадачности в работе – это сочетание следующих качеств: аналитическое мышление, системный подход, высокая организованность. Требования не самые простые, но чтобы их выработать, рекомендуем придерживаться следующих рекомендаций:
- Планируйте дела на день, неделю, месяц вперед. Бывает полезно даже прописать задачи на 1-2 часа, чтобы четко и вовремя их выполнить. Однако не составляйте нереальный план – это один из «хитрых» способов прокрастинации. Список дел должен мотивировать на достижение конкретных задач, промежуточные цели должны быть осуществимы за 1-2 итерации, мозг не должен быть забит лишней информацией. Ещё одно преимущество реального плана в том, что вам проще будет мотивировать себя на выполнение простой задачи.
- Распределите задачи по важности. Самые важные дела начинайте с утра. Помните принцип 20 на 80? Сначала делайте то, что приближает к поставленной цели. Думайте как стратег. Используйте уже проверенные методики Брайана Трейси «АБВГД», Дуайта Эйзенхауэра «Матрица» и, например, почитайте об эффекте Блюмы Зейгарник.
- Зациклите работу. Что значит многозадачность в «правильном» понимании этого термина? У вас может быть несколько дел, которые нужно выполнить за конкретный период времени. Если вы наброситесь на всё сразу, то не достигнете желаемого. Вдобавок получите стресс и депрессию. Чтобы решать эффективно, сосредотачивайтесь на каждой задаче. Например, возьмите на вооружение простой метод Франческо Чирилло, который называется «работать помидорами». То есть вы знаете, что можете продуктивно работать над задачей 45 минут, но потом вам требуется 10-15 отдыха. Возьмите таймер и поставьте период в три четверти часа. В это время полностью погрузитесь в выполнение дела. Как услышите сигнал – отдыхайте. Выпейте кофе, пообщайтесь в соцсетях, проверьте почту. Словом делайте то, что нравится. Отдохнув, снова заводите таймер и делайте работу. Давать отдых мозгу после режима концентрации полезно – это повышает эффективность в последующие отрезки времени.
- Не отвлекайтесь во время работы. Отключите в период концентрации над задачей все отвлекающие факторы – соцсети, оповещения на телефоне и электронной почте. Все это – пожиратели времени. Отведите определенные часы для проверки почты, просмотра аккаунтов и прочего. Не нужно каждые 10 минут листать ленту соцсетей в поиске новых сообщений.
- Разводите похожие виды деятельности и проекты на разное время. Наш мозг любит все упрощать и многие одинаковые дела сваливать в одну кучу. Именно поэтому, мы, находясь в здравом уме и светлой памяти, ставим электрический чайник на газовую печку, наносим на кожу зубную пасту вместо крема и делаем другие глупости. Например, вы можете довольно продуктивно соединить два дела: совершать покупки в мегамаркете и решать деловые вопросы по телефону. Эти действия из разных сфер, поэтому мозг видит различия и не смешивает все в одну кучу.
- Включайте музыку во время работы. Как ни странно, но звуки помогают лучше сосредоточиться и заряжают энергией. Конечно, музыка должна быть в тему – не напрягать, не отвлекать внимание на себя.
- Фиксируйте результаты. То есть переносите выполненные задачи в папку «завершенные» — это дисциплинирует мозг. Вы видите, что сделали за час, день, неделю, месяц и сколько осталось до финиша.
- Подключайте «напоминалки». Гаджеты могут стать вашими помощники в личной эффективности. Планируйте, на какое время поставить ту или иную задачу и, главное, выполняйте свой план.
- Старайтесь действовать последовательно, то есть делайте задачи одну за другой. Конечно, бывает необходимым выполнить сразу два дела за раз, но все хорошо в меру. Подходите к трате своих умственных ресурсов с позиции экономии: если не нужно напрягаться и включать режим многозадачности, то и не стоит этого делать.
- Отдыхайте разнообразно. Продуктивность в работе напрямую связана с качеством отдыха. Можно «пахать» 12 часов, приходить домой и падать без сил на кровать. А завтра снова на работу. Такой режим подходит для роботов, но у человека сильно творческое начало и продуктивность работы зависит от того, как он отдыхает после неё. Например, можно пролежать выходной на диване, уставившись в телевизор, или сходить в театр, музей, съездить с друзьями на пикник.
Многозадачность – это капризное и довольно сложное свойство психики человека. Если мы не сможем его обуздать, чтобы использовать себе во благо, то оно оседлает нас и выжмет все соки. Помните об этом!
Плюсы и минусы
Рассмотрим преимущества мультизадачности:
- При надлежащем планировании действительно можно эффективно решать несколько задач одновременно. То есть, выполняя дела, вы должны четко понимать, каких результатов должны достичь.
- Многозадачность помогает развить пластичность мышления и способность удержать в поле внимания несколько задач. Это неплохой тренажер для мозга.
- Способность делать несколько дел одновременно и делать это хорошо, помогает быстро реагировать на форс-мажорные обстоятельства, улучшает стратегическое мышление и видение ситуации. В некоторых нишах действительно полезно сразу охватить несколько направлений одновременно, проанализировать их перспективность и только потом принимать решения по каждому из них.
- Поверхностная обработка информации. Когда много всего, то мозг скользит по верхушках, не вникая в суть процессов. Такой человек берет общее изо всех сфер, но ни в одной не является профи.
- Высока вероятность ошибок. При недостаточной концентрации на задаче или при эффекте переноса данных с одной задачи на другую, неизменно совершаются ошибки. Внимание у многостаночника рассеивается, и это сильно вредит результату.
- Повышается утомляемость. Попытки ухватиться за всё сразу требует больших затрат энергии как физической, так и умственной. Человек быстрее устает, а продуктивность стремится к нулю.
- Растут горы неоконченных дел. Лихо начать 10-20 дел одновременно никто не запрещает, но не стоит ждать такого же быстрого их завершения. Из 10 начатых дел к финишной черте доводят 1-2 задачи, при этом сорвав все сроки и потратив в разы больше усилий. А что с остальными? Они лежат и ждут своей участи – годами, десятилетиями.
Последствия многозадачности бывают крайне неприятными. Увеличивается когнитивная нагрузка, то есть приходится тратить больше умственных ресурсов на обработку потока информации. Снижается продуктивность работы, многостаночники зачастую неправильно оценивают свои возможности и недооценивают силу отвлекающих факторов. Снижается способность к концентрации внимания на задаче, многозадачность не ценится в среде высоких технологий, научных исследований и других сферах со сложными алгоритмами работы.
Многозадачность приводит к выгоранию. Люди, практикующие такой подход, нарушают естественные механизмы мотивации и вознаграждения, которые имеются в нашем мозге. Нейробиология доказала, что снижение плотности серого вещества в передней поясной коре головного мозга из-за стресса приводит к потере радости от мыслительных усилий.
Совмещение дел может быть опасным для жизни и здоровья. Например, вы находитесь за рулем автомобиля и пытаетесь одновременно вести переговоры с партнером. Вероятность аварии возрастает в разы.
Резюме
Мы узнали, что такое многозадачность. Изучили, как работать в таком режиме, какие есть плюсы и минусы выполнения нескольких дел одновременно. Мультизадачность можно использовать для тренировки пластичности мозга, однако в рабочей среде полезнее развивать навык последовательного выполнения дел. Тише едешь – дальше будешь!
Источник
Национальная библиотека им. Н. Э. Баумана
Bauman National Library
Персональные инструменты
Многозадачность (Операционные Системы)
Многозада́чность – понятие из теории операционных систем, под которым подразумевается обеспечение возможности параллельной (или псевдопараллельной) обработки нескольких процессов. Однако, идеальная многозадачность ОС возможна только в распределённых вычислительных системах.
Другими словами, многозадачностью можно назвать способ исполнения нескольких задач в один промежуток времени. При этом задачи распределяют между собой общие ресурсы (resources sharing), а также выполняют планирование (scheduling) задачи в очереди исполнения.
Сущусвуют однозадачные системы, которые не обладают свойством многозадачности, т.е. в такой ОС задачи исполняются последовательно. [Источник 1]
Содержание
Свойства многозадачной среды
Примитивные многозадачные среды обеспечивают чистое «разделение ресурсов», когда за каждой задачей закрепляется определённый участок памяти, и задача активизируется в строго определённые интервалы времени.
Более развитые многозадачные системы проводят распределение ресурсов динамически, когда задача стартует в памяти или покидает память в зависимости от её приоритета и от стратегии системы. Такая многозадачная среда обладает следующими особенностями:
- Каждая задача имеет свой приоритет, в соответствии с которым получает процессорное время и память
- Система организует очереди задач так, чтобы все задачи получили ресурсы, в зависимости от приоритетов и стратегии системы
- Система организует обработку прерываний, по которым задачи могут активироваться, деактивироваться и удаляться
- По окончании положенного кванта времени ядро временно переводит задачу из состояния выполнения в состояние готовности, отдавая ресурсы другим задачам. При нехватке памяти страницы невыполняющихся задач могут быть вытеснены на диск (своппинг), а потом, через определённое системой время, восстанавливаться в памяти
- Система обеспечивает защиту адресного пространства задачи от несанкционированного вмешательства других задач
- Система обеспечивает защиту адресного пространства своего ядра от несанкционированного вмешательства задач
- Система распознаёт сбои и зависания отдельных задач и прекращает их
- Система решает конфликты доступа к ресурсам и устройствам, не допуская тупиковых ситуаций общего зависания от ожидания заблокированных ресурсов
- Система гарантирует каждой задаче, что рано или поздно она будет активирована
- Система обрабатывает запросы реального времени
- Система обеспечивает коммуникацию между процессами [Источник 1]
Трудности реализации многозадачной среды
Основной трудностью реализации многозадачной среды является её надёжность, выраженная в защите памяти, обработке сбоев и прерываний, предохранении от зависаний и тупиковых ситуаций.
Кроме надёжности, многозадачная среда должна быть эффективной. Затраты ресурсов на её поддержание не должны: мешать процессам проходить, замедлять их работу, резко ограничивать память. [Источник 1]
История многозадачных операционных систем
Поначалу реализация многозадачных операционных систем представляла собой серьёзную техническую трудность, отчего внедрение многозадачных систем затягивалось, а пользователи долгое время после внедрения предпочитали однозадачные.
В дальнейшем, после появления нескольких удачных решений, многозадачные среды стали совершенствоваться, и в настоящее время употребляются повсеместно.
Впервые многозадачность операционной системы была реализована в ходе разработки операционной системы Multics (1964 год). Одной из первых многозадачных систем была OS/360 (1966), используемая для компьютеров фирмы IBM и их советских аналогов ЕС ЭВМ. Разработки системы были сильно затянуты, и на начальное время фирма IBM выдвинула однозадачный DOS, чтобы удовлетворить заказчиков до полной сдачи OS/360 в эксплуатацию. Система подвергалась критике по причине малой надёжности и трудности эксплуатации.
В 1969 году на основе Multics была разработана система 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 и Ada требуют поддержки многозадачности вне привязки к какой-либо операционной системе. В результате, популярная в первой половине 1990-х годов реализация языка программирования TopSpeed Модула-2 от JPI/Clarion позволяляла организовывать различные типы многозадачности (кооперативную и вытесняющую — см. ниже) для потоков одной программы в рамках такой принципиально однозадачной операционной системы, как MS-DOS. Это осуществлялось путём включения в модуль программы компактного планировщика задач, содержащего обработчик таймерных прерываний . Языки программирования, обладающие таким свойством, иногда называют языками реального времени. [Источник 1]
Классификация
По типу наименьшего элемента управляемого кода
Процессная многозадачность.
Здесь программа — наименьший элемент управляемого кода, которым может управлять планировщик операционной системы. Известна большинству пользователей (одновременная работа в текстовом редакторе и прослушивание музыки). Многозадачная система позволяет двум или более программам выполняться одновременно.
Процесс — это понятие, относящееся к операционной системе. Каждый раз при запуске приложения создается и запускается новый процесс. С каждым процессом связаны следующие ресурсы, как:
- виртуальное адресное пространство;
- исполнимый код и данные;
- базовый приоритет;
- описатели объектов;
- переменные окружения.
Поточная многозадачность.
Многопоточность — специализированная форма многозадачности. Наименьший элемент управляемого кода — поток. Многопотоковая (multi-threaded) система предоставляет возможность одновременного выполнения одной программой 2 и более задач (потоков). Поток (thread) — это основной элемент системы, которому ОС выделяет машинное время. Поток может выполнять какую-то часть общего кода процесса, в том числе и ту часть, которая в это время уже выполняется другим потоком.
Потоки и процессы:
- Поток определяет последовательность исполнения кода в процессе.
- Процесс ничего не исполняет, он просто служит контейнером потоков.
- Потоки всегда создаются в контексте какого-либо процесса, и вся их жизнь проходит только в его границах.
- Потоки могут исполнять один и тот же код и манипулировать одними и теми же данными, а также совместно использовать описатели объектов ядра, поскольку таблица описателей создается не в отдельных потоках, а в процессах.
- Т.к. потоки расходуют существенно меньше ресурсов, чем процессы, следует решать свои задачи за счет использования дополнительных потоков и избегать создания новых процессов.
По способу организации времени выполнения каждого процесса
Параллельная многозадачность
Идеальным случаем многозадачности является параллельная многозадачность, когда каждая задача исполняется в своём аппаратном микропроцессорном ядре действительно одновременно друг с другом. Истинная многозадачность операционной системы возможна только в распределенных вычислительных системах. Реализация данного типа многозадачности требует больших материальных вложений (требуется отдельное аппаратное средство для каждой задачи), поэтому обычно её применение не является целесообразным. Ниже представлен пример системы , в которой реализована параллельная многозадачность.
Микроконтроллер Propeller от Parallax обеспечивает работу сразу 8 задач. Восемь встроенных процессоров-ядер, могут выполнять как совместные, так и независимые задачи, получая доступ к разделяемым ресурсам посредством центрального переключающего устройства. Разработчик полностью контроллирует, как и когда загружать каждое из ядер; ни компилятор, ни какая-либо операционная система не распределяет задачи между несколькими ядрами. Общий источник тактовой частоты обеспечивает всем процессорам единую временную базу и синхронизацию. Контроллер имеет два возможных языка программирования: легкий для освоения высокоуровневый язык Spin, а так же низкоуровневый Propeller Ассемблер (см. рис. 1). [Источник 2]
Рисунок 1 – Propeller Parallax
Альтернативой параллельной многозадачности является применение псевдопараллельной многозадачности или совокупности параллельной и псевдопараллельной многозадачности при наличии нескольких процессорных ядер.
Типы псевдопараллельной многозадачности
Невытесняющая многозадачность
16-и разрядная Windows уже стала поддерживать и вытесняющую многозадачность (non-preemptive multitasking). Такой тип многозадачности стал возможен благодаря основанной на сообщениях архитектуре Windows.Windows – программа может находиться в памяти и не выполняться до тех пор, пока не получила сообщение. Ранее, эти сообщения часто являлись прямым или косвенным результатом ввода информации пользователем с клавиатуры или мыши. Сейчас, механизм посылки сообщений широко используется и для обмена данными, инициации какого-либо действия приложения и т.п.
При всем при этом, Windows использовала вытесняющую многозадачность для выполнения DOS – программ, а также позволяла некоторым программам, например, для целей мультимедиа, получать аппаратные прерывания от таймера.
Существенным ограничением такого подхода является то, что время, затрачиваемое программой на обработку сообщения может быть очень большим, а управление операционной системе передается только после обработки сообщения.
Частично преодолеть последнее ограничение, можно, опять таки используя таймер для периодической смене выполняемых программ. Другим решением по преодолению невытесняющей многозадачности является вызов функции PeekMessage . Обычно программа использует вызов функции GetMessage для извлечения сообщений из очереди. Однако, если в данный момент времени очередь сообщений пуста, то функция GetMessage будет ждать поступления сообщения в очередь, а затем возвратит его. Функция PeekMessage работает иначе – она возвращает управление программе даже в том случае, если сообщений в очереди нет. Таким образом, выполнение работы, требующей больших затрат времени, будет продолжаться до того момента, пока в очереди не появятся сообщения для данной или любой другой программы.
Плюсы | Минусы |
---|---|
простота реализации | затруднена оперативная реакция на внешние события |
предсказуемость в поведении, исключение некоторых нежелательных ситуаций, таких как голодание (starvation),гонка (race condition) | незащищенность задач друг от друга, снижение надёжности системы — как правило одна неправильно работающая задача блокирует или нарушает работу остальных |
минимальные требования к системе и минимизация затрат ресурсов |
Совместная или кооперативная многозадачность
Первые операционные системы, реализованные на персональных компьютерах, сильно уступали в концептуальном плане и по своим реальным возможностям системам с разделением времени, давно реализованным в mainframe- компьютерах. В Win 16, например, тоже существует понятие многозадачности. Реализовано оно следующим образом: обработав очередное сообщение, приложение передает управление операционной системе, которая может передать управление другому приложению. Такой вид многозадачности, при котором операционная система передает управление от одного приложения другому не в любой момент времени, а только когда текущее приложение отдает управление системе, получил, как было упомянуто, название кооперативной многозадачности (cooperative multi-tasking).
Плюсы | Минусы |
---|---|
отсутствие необходимости защищать все разделяемые структуры данных, что упрощает разработку, особенно перенос кода из однозадачных сред в многозадачные. | неспособность всех приложений работать в случае ошибки в одном из них, приводящей к отсутствию вызова операции «отдать процессорное время» |
затрудненная возможность реализации многозадачной архитектуры ввода-вывода в ядре ОС, позволяющей процессору исполнять одну задачу в то время, как другая задача инициировала операцию ввода-вывода и ждет её завершения |
Вытесняющая, или приоритетная, многозадачность (режим реального времени)
В Windows начиная с Windows 95 реализован принципиально другой вид многозадачности, в котором операционная система действительно контролирует и управляет процессами, потоками и их переключением. Способность операционной системы прервать выполняемый поток практически в любой момент времени и передать управление другому ожидающему потоку определяется термином preemptive multitasking — преимущественная, или вытесняющая, многозадачность. Реализация ее выглядит так: все существующие в данный момент потоки, часть из которых может принадлежать одному и тому же процессу, претендуют на процессорное время и, с точки зрения пользователя должны выполняться одновременно. Для создания этой иллюзии система через определенные промежутки времени забирает управление, анализирует свою очередь сообщений, распределяет сообщения по другим очередям в пространстве процессов и, если считает нужным, переключает потоки (см. рис. 2).
Схема обработки прерывания следующая:
- Работа основной программы пользователя.
- Возникновение прерывания.
- Сохранение параметров работающей программы (регистров процессора).
- Переход по адресу процедуры обработки прерывания.
- Выполнение процедуры обработки прерывания.
- Восстановление параметров работающей программы.
- Переход по адресу следующей команды основной программы.
Прерывания с более высоким приоритетом, в свою очередь, могут прервать обработку текущего прерывания и т.д.
Реализация вытесняющей многозадачности в Windows 2000 дает не только возможность плавного переключения задач, но и устойчивость среды к зависаниям, так как ни одно приложение не может получить неограниченные права на процессорное время и другие ресурсы. Так система создает эффект одновременного выполнения нескольких приложений. Если компьютер имеет несколько процессоров, то системы Windows NT/2000 могут действительно совмещать выполнение нескольких приложений. Если процессор один, то совмещение остается иллюзией. Когда заканчивается квант времени, отведенный текущей программе, система ее прерывает, сохраняет контекст и отдает управление другой программе, которая ждет своей очереди. Величина кванта времени (time slice) зависит от ОС и типа процессора, в Windows NT она в среднем равна 20 мс. Следует отметить, что добиться действительно одновременного выполнения потоков можно только на машине с несколькими процессорами и только под управлением Windows NT/2000, ядра которых поддерживают распределение потоков между процессорами и процессорного времени между потоками на каждом процессоре. Windows 95 работает только с одним процессором. Даже если у компьютера несколько процессоров, под управлением Windows 95 задействован лишь один из них, а остальные простаивают. [Источник 3]
Рисунок 2 – Переключение потоков
Плюсы | Минусы |
---|---|
переключение между задачами полностью возложено на диспетчер задач, и задача выполняется как в однозадачном окружении(пока от задачи не требуется взаимодействие с другими задачами или доступ к общим ресурсам) | требуются специальные методы синхронизации задач друг с другом во избежание неопределённых ситуаций и конфликтов |
задача может оперативно получить управление в случае необходимости вне зависимости от состояния других задач, что обеспечивает работу в реальном времени | требуется поддержка со стороны аппаратного обеспечения (как минимум для сохранения и восстановления состояния микропроцесора при переключении) |
возможности реализации защиты операционной системой задач от ошибок и атак | требует больше системных ресурсов (память под стек и сохранение состояния для каждого процессора и время на переключение контекстов) |
Диспетчеризация
Эффективность многозадачной системы во многом зависит от способа диспетчеризации задач на исполнение.
Состояние задачи
Для понимания диспетчеризации важным является понятие состояния задачи. Основные состояния задач такие:
- выполняется;
- готова к исполнению;
- заблокирована.
Задача находится в состоянии исполнения тогда, когда под неё выделен ресурс процессора и передано управление. Очевидно, что в системе не может быть выполняющихся задач больше, чем физических процессоров. Поэтому существует второе состояние — готовность к исполнению. Задача в это состояние тогда, когда она может исполняться, то есть не существует причин, вызывающих блокировку, но вычислительные ресурсы отданы под другие задачи. В третье состояние задача попадает при невозможности её исполнения в данный момент времени.
- ожидание какого либо события ;
- незавершённая инициализация (когда ещё не созданы другой задачей или системой начальные условия для запуска);
- «заморозка» (явная остановка исполнения, обычно в отладочных целях);
- завершение (состояние , когда исполнение уже закончено, но ресурсы ещё не освобождены);
- специфические случаи.
В отличие от первых двух, состояние блокировки, вообще говоря не является обязательным.
Стратегии диспетчеризации
Известно несколько основных стратегий диспетчеризации:
- круговая (round-robin).Управление между задачами производится в в каком-либо фиксированном порядке через определённые промежутки времени;
- случайная (random).Через каждый определённый промежуток времени управление передаётся на произвольную задачу;
- приоритетная (priority-driven).Каждая задача имеет уровень приоритета и управление получает незаблокированная задача имеющая наибольший уровень;
- управляемая дедлайнами (deadline-driven). Передача управления производится в порядке, обеспечивающем выполнение задач в определённый срок. [Источник 1]
Программная реализация многозадачности
Когда пользователь запускает программу, Windows создает в памяти компьютера экземпляр программы, называемый процессом. Процесс не является точной копией *.ехе – файла, как это было, например в операционной системе DOS. Процесс содержит в себе копию *.ехе – файла, а также некоторую другую информацию о функционировании данного приложения. В этой дополнительной информации хранятся, например, границы выделенной приложению памяти, что помогает отслеживать корректность обращения к оперативной памяти со стороны приложения. Так как Windows поддерживает механизм виртуальной памяти, то среди этой информации находятся сведения о расположении сегментов программы. Здесь же содержится командная строка, формируемая при запуске программы.
Запустить процесс можно как при помощи командной строки системного меню Windows, при помощи программы Проводника, так и программно, из другого приложения. Это можно выполнить при помощи функций API :
Для 16-битных приложений используется функция WinExec :
Первый параметр является командной строкой, в которой указывается имя файла и параметры, указываемые после имени загружаемого файла.
После запуска, программа начинает параллельную работу относительно приложения-родителя и ее выполнение не зависит от других приложений, если, конечно, зависимость не предусмотрена самой природой приложений.
В среде Windows 32 следует использовать другой способ порождения процессов:
Первый параметр является указателем на имя запускаемого файла. Имя может содержать полный путь к файлу (диск:\каталог\…\файл). Если имя не содержит пути, то операционная система ищет файл в текущем каталоге, затем в системных каталогах и в каталогах, указанных в разделе PATH при загрузке системы.
Второй параметр указывает на командную строку.
Третий и четвертый параметры определяют, может ли возвращаемый указатель процесса наследоваться дочерними процессами и потоками.
bInheritHandles и dwCreationFlags содержит дополнительные флаги управления созданием и приоритетом процесса.
lpEnvironment содержит указатель на буфер памяти, в котором будет создаваться служебная информация по процессу. Если равен NULL, то операционная система сама отводит место в памяти под эту информацию.
lpCurrentDirectory указатель на строку, содержащую путь к каталогу, который будет использоваться запускаемым процессом как текущий. Если значение поля равно, то текущей директорией будет считаться каталог, являющийся текущим для процесса-родителя.
lpStartupInfo определяет структуру STARTUPINFO , которая описывает окно, создаваемое для запускаемого процесса (в ней содержится информация, похожая на ту, которая передается в процедуру CreateWindow).
lpProcessInformation указатель на структуру, заполняемую после создания нового процесса. Структура содержит информацию о созданном процессе.
Многопоточность в программе реализовать можно несколькими путями.
Непосредственное использование системного таймера для указание процедуры, вызываемой периодически. Данный способ был рассмотрен в лекции «Использование Таймера». Это типичный представитель вытесняющей многозадачности. К достоинствам этого способа можно отнести то, что программа может устанавливать и изменять период вызова функции.
Использование системного таймера для организации посылки синхронных сообщений выбранному окну (порядок организации описан в лекции «Использование Таймера»). С помощью данного способа реализуется невытесняющая многозадачность. Достоинство – изменяемая периодичность посылки сообщений. Недостаток – природа синхронных сообщений не гарантирует четкое выполнение периода прихода сообщений от таймера.
Создание потоков. Данный способ подразумевает определение некоторой процедуры потока, которая запускается параллельно основному процессу приложения. Момент окончания выполнения потока контролирует сама поточная процедура.
Первый параметр определяет атрибуты безопасности для запускаемого потока. Если он равен NULL, то данный поток не может использоваться дочерними процессами.
Второй параметр определяет начальный адрес потока (фактически — имя процедуры потока), например:
Третий параметр является целым числом, которое передается создаваемому потоку как параметр pvoid . В данном случае в качестве данного параметра выступает указатель на некоторую структуру данных. Таким образом, основной процесс имеет возможность передавать в поток необходимую информацию.
Четвертый параметр определяет дополнительные флаги создания потока. Если этот параметр равен нулю, то поток создастся немедленно.
Последний параметр является адресом переменной, в которую возвращается идентификатор потока.
Использование функции Sleep
Итак, поток – это часть программы, запускаемая параллельно другим задачам процесса. Поток сам определяет как долго ему находится в памяти и какие действия надо совершать. Если поток должен периодически совершать одни и те же действия (например, обновлять экран или проверять почту), то самым естественным способом сделать это является организация бесконечного цикла (подобного циклу обработки сообщений). Однако, в этом случае не определено время цикличности, т.к. временные периоды выполнения потока определены операционной системой. Кроме того, как только одна итерация цикла заканчивается, начинается другая. Как же вызвать приостановку выполнения потока? Для этих целей существует функция Sleep, которая в качестве единственного параметра имеет время, задаваемое в миллисекундах. Функция не осуществляет возврата до тех пор, пока не истечет указанное время. При этом другие потоки и процессы работают в обычных режимах. Если параметр этой функции равен нулю, то операционная система просто лишает текущий поток оставшегося кванта времени.
Следует отметить, что данная функция не освобождает полностью процессор от исполнения потока. Действительно, процессор периодически должен проверять истекло ли время, заданное в функции. То есть, речь идет не о приостановке периодического выполнения потока, а лишь о задержке выполнения алгоритма потока на одной его команде (Sleep). [Источник 4]
Критические разделы
В многопоточной среде часто возникают проблемы, связанные с использованием параллельно исполняемыми потоками одних и тех же данных или устройств. Например, один из потоков, получает данные извне и помещает их в некоторый буфер памяти компьютера; Другой поток выбирает эти данные из буфера и отображает их на экран. Теперь представьте, что первый поток занес изменил только половину данных в буфере, операционная система переключилась на выполнение второго потока, и второй поток вывел на экран половину новых и половину старых данных.
В других случаях одновременное обращение к памяти может привести к неправильной работе программ, зависанию программы, потере данных и т.п.
Один из путей устранения конфликта состоит в том, что программист может определить участок потока, который должен быть выполнен без прерывания, т.е. пока участок потока не будет выполнен до конца, никакой из потоков данного процесса не будет выполняться.
Данный участок потока называется критическим разделом. Существует четыре функции работы с критическим разделом. Чтобы их использовать необходимо определеить объект типа критический раздел:
Объект типа критический раздел сначала должен быть инициализирован одним из потоков программы с помощью функции:
Эта функция создает критический раздел с именем cs.После инициализации объекта «критический раздел» поток входит в критический раздел, вызывая функцию:
В этот момент поток становиться владельцем объекта. Два различных потока не могут быть владельцами одного объекта одновременно. Следовательно, если один поток вошел в критический раздел, то следующий поток, вызывая функцию EnterCriticalSection(&cs) ; с тем же самым объектом, будет задержан внутри функции. Возврат из функции произойдет только тогда, когда первый поток покинет критический раздел, вызвав функцию:
В этот момент второй поток, задержанный в функции EnterCriticalSection(&cs) , станет владельцем критического раздела, и его выполнение будет возобновлено.
Когда критический раздел больше не нужен вашей программе, его можно удалить с помощью функции:
Это приведет к освобождению всех ресурсов системы, задействованных для поддержки объекта критический раздел.
Программа может создавать несколько критических разделов. Существенное ограничение при использовании критических разделов состоит в том, что таким образом можно синхронизировать только потоки одного процесса и нельзя осуществить синхронизацию процессов (действительно, ведь переменная cs объявлена в процессе и не видна из других процессов). [Источник 4]
Использование событий
Альтернативным вариантом синхронизации является использование событий. Объект событие может быть либо свободным (signaled) или установленным (set), либо занятым (non-signaled) или сброшенным (reset). Вы можете создать объект «событие» с помощью функции:
Первый параметр — указатель на структуру SECURITY_ATTRIBUTES, устанавливающую параметры использования события потоками и процессами.
Параметр fInitial устанавливается в TRUE, если вы хотите, чтобы объект Событие был изначально свободным, или в FALSE, чтобы он был занятым.
Параметр psz Name определяет имя события. По этому имени разные процессы могут использовать одно событие.
Для того, чтобы сделать свободным существующий объект Событие, надо вызвать функцию:
Чтобы сделать объект Событие занятым, вызывается функция:
Для синхронизации используется функция:
где второй параметр имеет значение INFINITE. Возврат из функции происходит немедленно, если объект событие в настоящее время свободен. В противном случае поток будет приостановлен в функции до тех пор, пока событие не станет свободным. Вы можете установить значение тайм-аута во втором параметре, задав его величину в миллисекундах. Тогда возврат из функции произойдет, когда объект Событие станет свободным или истечет тайм-аут.
Если параметр fManual имеет значение FALSE при вызове функции CreateEvent , то объект Событие автоматически становится занятым, когда осуществляется возврат из функции WaitForSingleObject . Эта особенность позволяет избежать использования функции ResetEvent . [Источник 4]
Проблемные ситуации в многозадачных системах
Рисунок 3 – Взаимосвязь потоков и процессов
Голодание (starvation)
Задержка времени от пробуждения потока до его вызова на процессор, в течение которой он находится в списке потоков, готовых к исполнению. Возникает по причине присутствия потоков с большими или равными приоритетами, которые исполняются все это время.
Негативный эффект заключается в том, что возникает задержка времени от пробуждения потока до исполнения им следующей важной операции, что задерживает исполнение этой операции, а следом за ней и работу многих других компонентов.
Голодание создаёт узкое место в системе и не дает выжать из неё максимальную производительность, ограничиваемую только аппаратно обусловленными узкими местами.
Любое голодание вне 100 % загрузки процессора может быть устранено повышением приоритета голодающей нити, возможно — временным.
Как правило, для предотвращения голодания ОС автоматически вызывает на исполнение готовые к нему низкоприоритетные потоки даже при наличии высокоприоритетных, при условии, что поток не исполнялся в течение долгого времени (
10 секунд). Визуально эта картина хорошо знакома большинству пользователей Windows — если в одной из программ поток зациклился до бесконечности, то переднее окно работает нормально, несмотря на это — потоку, связанному с передним окном, Windows повышает приоритет. Остальные же окна перерисовываются с большими задержками, по порции в секунду, ибо их отрисовка в данной ситуации работает только за счет механизма предотвращения голодания (иначе бы голодала вечно).
Гонка (race condition)
Недетерминированный порядок исполнения двух потоков кода, обрабатывающими одни и те же данные, исполняемыми в двух различных потоках (задачах). Приводит к зависимости порядка и правильности исполнения от случайных факторов.
Устраняется добавлением необходимых блокировок и примитивов синхронизации. Обычно является легко устраняемым дефектом (забытая блокировка).
Инверсия приоритета
Поток L имеет низкий приоритет, поток M — средний, поток H — высокий. Поток L захватывает mutex, и, выполняясь с удержанием mutex’а, прерывается потоком M, который пробудился по какой-то причине, и имеет более высокий приоритет. Поток H пытается захватить mutex.
В полученной ситуации поток H ожидает завершения текущей работы потоком M, ибо, пока поток M исполняется, низкоприоритетный поток L не получает управления и не может освободить mutex.
Устраняется повышением приоритета всех нитей, захватывающих данный mutex, до одного и того же высокого значения на период удержания mutexa. Некоторые реализации mutex’ов делают это автоматически. [Источник 4]
Процессы в Windows и потоковая многозадачность
Рисунок 4 – Пример работы планировщика
Windows — это многозадачная операционная система, то есть она может одновременно выполнять две и более программ. Конечно, программы используют единственный процессор и, строго говоря, выполняются не одновременно. Однако высокое быстродействие компьютера создает такую иллюзию. Windows поддерживает два типа многозадачности: процессную и потоковую (см. рис. 3).
Процессная многозадачность заключается в том, что Windows может выполнять одновременно более одной программы. Таким образом, Windows поддерживает «традиционную» процессную многозадачность.
В Windows процесс может иметь несколько (много) потоков.
Windows способна управлять потоками, каждый процесс может иметь несколько потоков, следовательно, любой процесс может иметь две или более частей, выполняющихся одновременно. Таким образом, работая в ОС Windows, можно одновременно выполнять как несколько программ, так и частей отдельной программы.
Windows позволяет выполняться нескольким приложениям одновременно, при этом каждое приложение по очереди получает малый отрезок времени для выполнения, после чего наступает черед другого приложения. Процессор совместно используется несколькими выполняющимися процессами. Определить, какой именно процесс будет выполняться следующим и какое процессорное время выделяется каждому из приложений, — задача планировщика.
Планировщик может быть очень простым, обеспечивающим выполнение каждого из процессов одинаковое количество миллисекунд, а может работать с учетом различных уровней приоритета приложений, вытесняя низкоприоритетные приложения. Windows при запуске приложения и планирует его работу, и со стороны пользователя для этого не требуется никаких специальных действий.Рассмотреть наглядно простейший пример переключения между задачами можно на рисунке 4.
Windows — это не только многозадачная, но и многопоточная операционная система. Это означает, что в действительности программы состоят из ряда более простых потоков выполнения. Выполнение этих потоков планируется так же, как и выполнение более мощных процессов. [Источник 5]
Многозадачность в Linux
Linux — считается многозадачной операционной системой. Ядро Linux постоянно переключает процессы, при этом происходит довольно быстро, поэтому нам кажется, что процессы работают одновременно.
Одни процессы могут порождать другие процессы, образовывая древовидную структуру. Порождающие процессы называются родителями или родительскими процессами, а порожденные — потомками или дочерними процессами. На вершине этого «дерева» находится процесс init, который порождается автоматически ядром в процесссе загрузки системы.
К каждому процессу в системе привязаны идентификатор процесса PID (Process IDentifier) и идентификатор родительского процесса PPID (Parent Process IDentifier). Для каждого процесса PID является уникальным (в конкретный момент времени), а PPID равен идентификатору процесса-родителя.
Использование getpid() и getppid()
Процесс может узнать свой идентификатор (PID), а также родительский идентификатор (PPID) при помощи системных вызовов getpid() и getppid().
Системные вызовы getpid() и getppid() имеют следующие прототипы: pid_t getpid (void) ; pid_t getppid (void) ;
Для использования getpid() и getppid() в программу должны быть включены директивой #include заголовочные файлы unistd.h и sys/types.h (для типа pid_t). Вызов getpid() возвращает идентификатор текущего процесса (PID), а getppid() возвращает идентификатор родителя (PPID). pid_t — это целый тип, размерность которого зависит от конкретной системы. Значениями этого типа можно оперировать как обычными целыми числами типа int.
Рассмотрим теперь простую программу, которая выводит на экран PID и PPID, а затем «замирает» до тех пор, пока пользователь не нажмет .
Проверим теперь, как работает эта программа. Для этого откомпилируем и запустим ее:
Теперь, не нажимая , откроем другое терминальное окно и проверим, правильность работы системных вызовов getpid() и getppid(): [Источник 4]
Источник