В длинной статье 4D вы узнаете, как восстановить процессы и потоки.

задняя часть

Процессы и потоки, о которых мы обычно говорим, больше основаны на перспективе языков программирования, так что вы действительно понимаете, что такое потоки и процессы? Итак, давайте посмотрим, что такое процессы и потоки с точки зрения операционной системы.

обработать

Основная концепция операционной системы заключается в следующем.进程, процесс — это абстракция работающей программы. Все остальное в операционной системе вращается вокруг процессов. Процессы — одна из старейших и наиболее важных концепций, предоставляемых операционными системами. Они поддерживают (псевдо) одновременные операции, даже если доступен только один ЦП. Они преобразуют один ЦП в ЦП нескольких виртуальных машин. Без абстракции процессов современная операционная система перестала бы существовать.

Все современные компьютеры делают много вещей одновременно.Люди, которые использовали компьютеры в прошлом, могут вообще не понять этого изменения.Давайте возьмем пример, чтобы проиллюстрировать этот момент: сначала рассмотрим веб-сервер, а запросы приходят с веб-страниц. При поступлении запроса сервер проверит, находится ли текущая страница в кеше, и если она есть в кеше, то напрямую вернет содержимое в кеше. Если кеша нет, то запрос будет передан на обработку на диск. Однако с точки зрения ЦП запросы к диску занимают больше времени, поскольку запросы к диску будут медленными. Когда запрос на жесткий диск будет завершен, поступит больше других запросов. При наличии нескольких дисков некоторые или все запросы могут быть выполнены последовательно к другим дискам до завершения первого запроса. Очевидно, что это явление параллелизма, и для управления явлением параллелизма необходимы условия контроля параллелизма.

Теперь рассмотрим ПК только с одним пользователем. При запуске системы в фоновом режиме также запускаются многие процессы, и пользователи обычно не знают о запуске этих процессов.Представьте себе, когда ваш собственный компьютер запускается, вы можете знать, какие процессы нужно запустить? Эти фоновые процессы могут быть процессом электронной почты, которому необходимо ввести электронную почту, или процессом уничтожения компьютерных вирусов для периодического обновления вирусной базы данных. Пользовательский процесс может распечатывать файлы и записывать компакт-диски, когда все пользователи находятся в сети, и эти действия необходимо контролировать. Следовательно, становится необходимой мультипрограммная система, поддерживающая несколько процессов.

Во многих многопрограммных системах ЦП будет进程Быстро переключайтесь между программами, заставляя каждую программу работать десятки или сотни миллисекунд. Однако, строго говоря, в определенный момент процессор может запускать только один процесс, но если мы определяем время в пределах 1 секунды, он может запускать несколько процессов. Это даст нам并行иллюзия. иногда люди говорят伪并行(pseudoparallelism)Это тот случай, когда нужно различать многопроцессорные системы (системы, в которых два или более ЦП совместно используют одну и ту же физическую память).

Давайте подробно объясним псевдопараллель:伪并行Относится к одноядерному или многоядерному процессору, выполняющему несколько процессов одновременно, что делает программу быстрее. Благодаря быстрому переключению ЦП между программами через очень ограниченные промежутки времени создается ощущение параллелизма. Недостатком является то, что время может быть выделено или не выделено следующему процессу.

Нам трудно отслеживать несколько параллельных процессов, поэтому после многих лет усилий разработчики операционных систем разработали концептуальную модель (последовательный процесс) для описания параллелизма, упрощающую понимание и анализ параллелизма.Обсуждение этой модели также является предметом этой статьи

модель процесса

В модели процесса все программное обеспечение, работающее на компьютере, часто включая операционную систему, организовано как ряд顺序进程(sequential processes), Упоминается как进程(process). Процесс — это экземпляр исполняемой программы, а также процесс включает в себя текущие значения счетчика программ, регистров и переменных. Концептуально каждый процесс имеет свой собственный виртуальный ЦП, но на самом деле ЦП переключается между процессами.

Как показано на рисунке выше, это многопроцессорная программа с 4 программами, и счетчик программ меняется по-разному, так как процессы постоянно переключаются.

На приведенной выше диаграмме эти 4 программы разделены на 4 процесса с собственным потоком управления (т. е. каждый со своим счетчиком программ), и каждая программа работает независимо. Конечно, на самом деле существует только один физический счетчик программ, и логический счетчик программ каждой программы загружается в физический счетчик программ, когда она хочет работать. Когда программа завершит работу, ее физический счетчик программ станет реальным счетчиком программ, а затем поместит его обратно в логический счетчик процесса.

На изображении ниже мы видим, что после достаточно долгого наблюдения все процессы запущены,Но на самом деле в любой момент времени работает только один процесс..

В последующем обсуждении мы предполагаем случай только с одним процессором. Конечно, это предположение обычно не выполняется до сих пор, поскольку новые чипы обычно являются многоядерными чипами, содержащими 2, 4 или более процессоров. Но пока проще анализировать проблему, рассматривая только один ЦП за раз. Поэтому, когда мы говорим, что ЦП действительно может запускать только один процесс за раз, даже с двумя ядрами (или ЦП), каждое ядро ​​может запускать только один поток за раз.

Поскольку ЦП быстро переключается между процессами, время выполнения каждого процесса в ЦП неопределенно. И когда тот же процесс снова запускается в ЦП, время его выполнения внутри ЦП часто не фиксируется. Разница между процессом и программой очень тонкая, но давайте проведем различие на примере. Рассмотрим ученого-компьютерщика, который умеет готовить и делает торт на день рождения для своей дочери. У него есть рецепт праздничного торта, а на кухне есть все необходимое: мука, яйца, сахар, ванильный сок и т. д. В этой аналогии рецепт торта — это программа, программист — процессор, а прощение торта — входные данные. Процесс представляет собой сумму ряда рутинных действий ученых, таких как чтение рецептов, выбор различных ингредиентов и выпечка тортов.

Теперь предположим, что к ученому подбегает сын и говорит, что его в голову ужалила пчела, тогда ученый запишет, где он находится в процессе приготовления торта, а затем достанет руководство по оказанию первой помощи и выполнит шаги, описанные выше, чтобы реализовать это для его сына спасения. Здесь было бы переключение между процессами, где ученый (ЦП) переключался бы с приготовления торта (процесс) на оказание медицинской помощи (другой процесс). Дождавшись обработки раны, ученый вернется к шагу, где только что был записан торт, и продолжит делать.

Ключевая идея здесь в том, что认识到一个进程所需的条件, процесс представляет собой сумму определенного вида деятельности, у него есть процедуры, вход и выход, состояние. Один процессор может совместно использоваться несколькими процессами, и он использует некоторый алгоритм планирования, чтобы решить, когда остановить работу одного процесса и перейти к обслуживанию другого процесса. Следует также отметить, что если процесс выполняется дважды, он считается двумя процессами.

создание процесса

Операционная система нуждается в каком-то способе создания процессов. В очень простых системах или в тех случаях, когда операционная система предназначена для запуска одного приложения (например, контроллера в микроволновой печи), также может быть необходимо, чтобы все процессы запускались вместе при запуске системы. Но в универсальной системе, однако, должен быть какой-то способ создавать или уничтожать процессы по запросу во время выполнения, теперь нам нужно изучить это, вот как создаются процессы.

  • инициализация системы
  • Работающая программа выполняет системный вызов, который создает процесс (например, fork).
  • Запросы пользователей на создание нового процесса
  • Инициализировать пакетное задание

При запуске операционной системы обычно создается несколько процессов. Некоторые из них前台进程(numerous processes), то есть процессы, которые взаимодействуют с пользователями и работают на них. Некоторые работают в фоновом режиме и не взаимодействуют с конкретными пользователями, но фоновые процессы также имеют определенные функции. Например, создайте фоновый процесс для получения входящих электронных писем. Этот процесс большую часть времени спит, но просыпается всякий раз, когда приходит электронное письмо. Также можно спроектировать фоновый процесс для приема входящих запросов веб-страниц на компьютер и пробуждения при поступлении запроса для обработки входящих запросов веб-страниц. Процессы, которые выполняются в фоновом режиме для обработки таких действий, как электронная почта, веб-страницы, новости, печать и т. д., называются守护进程(daemons). Большие системы будут иметь много демонов. В UNIX,psПрограммы могут отображать запущенные процессы, а в Windows вы можете использовать диспетчер задач.

Помимо создания процессов на этапе запуска, некоторые новые процессы также могут быть созданы позже. Как правило, работающий процесс выдает системные вызовы для создания одного или нескольких новых процессов, помогающих ему выполнять свою работу. Создание нового процесса особенно полезно, когда работу можно легко выполнить вместе на основе нескольких связанных, но независимых взаимодействующих процессов. Например, если есть большой объем данных, которые необходимо получить по сети и обработать последовательно, проще создать процесс для чтения данных и помещения их в общий буфер, а второй процесс будет их извлекать и обрабатывать. обработайте его должным образом. В многопроцессорных системах запуск каждого процесса на отдельном ЦП также может ускорить работу.

Во многих интерактивных системах программу можно запустить, введя команду или дважды щелкнув значок. Любая из этих операций может опционально запускать новый процесс. В базовой системе UNIX, работающей под управлением X, новый процесс займет окно с которого оно было начато. Когда процесс запускается в Windows, он обычно не имеет окна, но может создать одно или несколько окон. Каждое окно может запускать процесс. Вы можете переключать окна и взаимодействовать с процессами с помощью мыши или команд.

Интерактивные системы — это компьютерные системы, характеризующиеся большим количеством взаимодействий между людьми и компьютерами, такие как игры, веб-браузеры, IDE и другие интегрированные среды разработки.

Последний случай создания процесса относится к пакетной системе мэйнфрейма. Пользователи отправляют пакетные задания в такой системе. Когда ОС решает, что у нее есть ресурсы для выполнения другой задачи, она создает новый процесс и запускает в нем следующее задание из входной очереди.

Технически, во всех этих случаях выполнение существующим процессом процесса означает создание нового процесса путем создания системного вызова. Процесс может быть запущенным пользовательским процессом, системным процессом или пакетной программой, вызываемой с клавиатуры или мыши. Это системные вызовы, которые создают новые процессы. Этот системный вызов указывает операционной системе создать новый процесс и прямо или косвенно указывает, какую программу запускать в нем.

В UNIX существует только один системный вызов для создания нового процесса, и этот системный вызовfork. Этот вызов создает копию, связанную с вызывающим процессом. После разветвления родительский и дочерний процессы будут иметь один и тот же образ памяти, одни и те же строки окружения и одни и те же открытые файлы. Обычно дочерний процесс будет выполнятьсяexecveИли простой системный вызов для изменения образа памяти и запуска новой программы. Например, когда пользователь вводит команду сортировки в оболочке, оболочка разветвляет дочерний процесс, и дочерний процесс выполняет команду сортировки. Причина этого двухэтапного процесса состоит в том, чтобы позволить дочернему процессу манипулировать своим файловым дескриптором после fork, но перед execve для выполнения перенаправления стандартного ввода, стандартного вывода и стандартной ошибки.

В Windows все наоборот, простой вызов функции Win32CreateProcess, который обрабатывает создание процесса и загружает правильную программу в новый процесс. Этот вызов будет иметь 10 параметров, включая исполняемую программу, параметры командной строки для ввода в программу, различные атрибуты безопасности, наследует ли открытый файл управляющие биты, информацию о приоритете, спецификацию окна, которое должен создать процесс, и указатель на Указатель на структуру, в которой информация о вновь созданном процессе возвращается вызывающей стороне. КромеCreateProcessВ Win 32 есть около 100 других функций, которые управляют процессами, синхронизацией и соответствующими транзакциями. Ниже приведено сравнение системных вызовов операционной системы UNIX и операционной системы Windows.

UNIX Win32 иллюстрировать
fork CreateProcess создать новый процесс
waitpid WaitForSingleObject дождаться завершения процесса
execve none CraeteProcess = fork + servvice
exit ExitProcess прекратить выполнение
open CreateFile Создайте файл или откройте существующий файл
close CloseHandle закрыть файл
read ReadFile Чтение данных из одного файла
write WriteFile записать данные в один файл
lseek SetFilePointer Переместите указатель файла
stat GetFileAttributesEx получить разные атрибуты файла
mkdir CreateDirectory Создать новый каталог
rmdir RemoveDirectory удалить пустой каталог
link none Win32 не поддерживает ссылку
unlink DeleteFile уничтожить существующий файл
mount none Win32 не поддерживает монтирование
umount none Win32 не поддерживает монтирование, поэтому и не поддерживает монтирование
chdir SetCurrentDirectory Изменить текущий рабочий каталог
chmod none Win32 не поддерживает безопасность
kill none Win32 не поддерживает сигналы
time GetLocalTime получить текущее время

В UNIX и Windows после создания процесса родительский и дочерний процессы имеют отдельные адресные пространства. Если один из процессов изменит слово в своем адресном пространстве, это изменение не будет видно другому процессу. В UNIX адресное пространство дочернего процесса является копией родительского процесса, но это два разных адресных пространства; недоступные для записи области памяти являются общими. Некоторые реализации UNIX разделяют текстовую область между ними, потому что ее нельзя изменить. В качестве альтернативы дочерний процесс разделяет всю память родительского процесса, но в этом случае память передается через写时复制(copy-on-write)Общая, что означает, что когда один из двух хочет изменить часть памяти, эта память сначала явно копируется, чтобы гарантировать, что изменение происходит в частной области памяти. Опять же, перезаписываемая память не может быть разделена. Однако для вновь созданного процесса действительно возможно совместное использование ресурсов создателя, например совместное использование открытых файлов. В Windows адресное пространство родительского процесса и адресное пространство дочернего процесса отличаются с самого начала.

прекращение процесса

После создания процесса он начинает выполняться и выполнять задачи. Однако ничто не вечно, в том числе и процессы. Процессы рано или поздно завершаются, но обычно их запускают:

  • 正常退出(自愿的)
  • 错误退出(自愿的)
  • 严重错误(非自愿的)
  • 被其他进程杀死(非自愿的)

Большинство процессов завершаются, потому что работа выполнена. Когда компилятор завершает компиляцию данной программы, компилятор выполняет системный вызов, чтобы сообщить операционной системе, что он выполнил свою работу. Этот вызов в UNIXexit, в винде естьExitProcess. Программное обеспечение на экране также поддерживает добровольное завершение. Текстовые процессоры, интернет-браузеры и подобные программы всегда имеют значок или пункт меню, который пользователь щелкает, чтобы указать процессу удалить все временные файлы, которые он блокирует открытыми, а затем завершить работу.

Вторая причина завершения процесса — найти серьезную ошибку, например, если пользователь выполнит следующую команду

cc foo.c	

Чтобы иметь возможность скомпилировать foo.c, но файл не существует, компилятор выдает объявление и завершает работу. Интерактивные процессы, обращенные к экрану, обычно не завершаются напрямую, когда указан неправильный аргумент, потому что это не имеет смысла с точки зрения пользователя, пользователь должен знать, что произошло, и хочет повторить попытку, поэтому приложение обычно выводит диалоговое окно, информирующее пользователя о том, что произошла системная ошибка и необходимо повторить попытку или выйти.

Третьей причиной завершения процесса является ошибка, вызванная процессом, обычно из-за ошибки в программе. Например, была выполнена недопустимая инструкция, ссылка на несуществующую память или делитель был равен 0 и т.д. В некоторых системах, таких как UNIX, процесс может уведомить операционную систему о том, что он хочет сам обработать какой-либо тип ошибки, при этом процесс получает сигнал (прерывание), а не напрямую завершать процесс при возникновении такой ошибки.

Четвертая причина завершения процесса заключается в том, что процесс выполняет системный вызов, который сообщает операционной системе завершить процесс. В UNIX этим системным вызовом является kill. Соответствующая функция в Win32 естьTerminateProcess(обратите внимание, что это не системный вызов),

иерархия процессов

В некоторых системах родительский и дочерний процессы каким-то образом связаны, когда один процесс создает другие процессы. Сам дочерний процесс создает дополнительные процессы, формируя иерархию процессов.

В UNIX процесс и все его потомки и потомки вместе образуют группу процессов. Когда пользователь отправляет сигнал с клавиатуры, сигнал отправляется всем членам текущей группы процессов, связанных с клавиатурой (обычно это все активные процессы, созданные в текущем окне). Каждый процесс может отдельно захватывать сигнал, игнорировать сигнал или выполнять действие по умолчанию, которое должно быть уничтожено сигналом.

Вот еще один пример, который можно использовать для иллюстрации роли слоев, рассмотримUNIXКак инициализировать себя при запуске. называетсяinitСпециальный процесс, отображаемый в загрузочном образе. Когда процесс инициализации запускается, он считывает файл, в котором сообщается, сколько у него терминалов. Затем создайте новый процесс для каждого терминала. Эти процессы ждут, пока пользователь войдет в систему. Если вход в систему успешен, процесс входа в систему запускает оболочку, ожидающую получения команд пользовательского ввода, которые могут запускать другие процессы и так далее. Таким образом, все процессы во всей операционной системе принадлежат одному дереву процессов, корнем которого является init.

Наоборот, в Windows нет понятия иерархии процессов, все процессы в Windows равны, единственное, что похоже на иерархию, это то, что при создании процесса родительский процесс получает специальный токен (называемый дескриптором), который может использоваться с для управления дочерним процессом. Однако этот токен также может быть передан другой операционной системе, чтобы не было иерархии. В UNIX процесс не может лишить своих потомков进程权. (Таким образом, это все еще сравнение Windows).

статус процесса

Хотя каждый процесс представляет собой отдельный объект со своим счетчиком программ и внутренним состоянием, между процессами все же существует взаимодействие. Результаты одного процесса могут быть использованы в качестве входных данных для другого процесса в командах оболочки.

cat chapter1 chapter2 chapter3 | grep tree

Первый процесс — это cat, который объединяет и выводит три файла. Второй процесс — это grep, который выбирает из входных данных ключевое слово, содержащееtree, в зависимости от относительной скорости двух процессов (которая зависит от относительной сложности двух программ и квантов времени ЦП, выделенных каждому), может произойти следующее:grepГотов к запуску, но процесс ввода не завершен, поэтому процесс grep необходимо заблокировать до завершения ввода.

Процесс блокируется, когда его дальнейшее выполнение логически невозможно, например, когда процесс ожидает входных данных, которые можно использовать. Также может случиться так, что процесс, который был готов, также завершается, потому что операционная система решила временно назначить ЦП другому процессу. Факторы, вызывающие эти две ситуации, совершенно разные:

  • Суть первого случая заключается в приостановке процесса, вы должны войти в командную строку пользователя, прежде чем сможете выполнить следующую операцию.
  • Второй случай — полностью техническая проблема операционной системы: не хватает ЦП, чтобы выделить каждому процессу свой собственный процессор.

Когда процесс запускается, он может пройти через следующие состояния

На рисунке присутствуют три состояния

  1. Состояние выполнения, состояние выполнения относится к времени, когда процесс фактически занимает время выполнения ЦП.
  2. Состояние готовности, состояние готовности относится к работоспособному состоянию, но прекращено, поскольку выполняются другие процессы.
  3. Состояние блокировки, процесс не может работать, если не произойдет какое-либо внешнее событие.

Логически, рабочее состояние и состояние готовности очень похожи. В обоих случаях это означает процесс可运行, но во втором случае кванты процессорного времени не получаются. Третье состояние отличается от первых двух тем, что процесс не может работать, а также не может работать, когда ЦП бездействует или ему нечем заняться.

Три состояния включают переключение между четырьмя состояниями, которое происходит, когда операционная система обнаруживает, что процесс не может продолжать выполнение.状态1циклический, в некоторых системах процесс выполняет системные вызовы, такие какpause, чтобы получить заблокированное состояние. В других системах, включая UNIX, процесс автоматически завершается, когда нет доступных входных данных для чтения из канала или специального файла (например, терминала).

Оба перехода 2 и 3 вызываются планировщиком процесса (частью операционной системы), и процесс даже не знает о них. Появление перехода 2 указывает на то, что планировщик процессов решил, что текущий процесс выполняется достаточно долго, чтобы другим процессам пора было выполнять квант времени ЦП. Переход 3 происходит, когда все остальные процессы уже запущены и настало время для первого процесса восстановить квант времени процессора.

Планирование программы относится к решению, какой процесс будет выполняться первым и как долго, что является важным моментом.. Было разработано множество алгоритмов, чтобы попытаться сбалансировать общую эффективность системы с конкурирующими требованиями отдельных процессов.

Переход 4 происходит, когда происходит внешнее событие, которого ожидает процесс (например, поступает некоторый ввод). Если в это время нет другого запущенного процесса, немедленно запускается переход 3, и процесс начинает выполняться, в противном случае процесс находится в фазе готовности, ожидая, когда ЦП будет бездействовать, прежде чем его очередь будет запущена.

Использование модели процесса облегчает понимание того, что происходит внутри операционной системы. Некоторые процессы запускают программы, которые выполняют команды, введенные пользователем. Другие процессы являются частью системы, и их задачи заключаются в выполнении некоторых из следующих задач: например, выполнение запросов файловой службы, управление рабочими данными дисков и ленточных накопителей и т. д. Когда происходит прерывание диска, система принимает решение остановить выполнение текущего процесса и вместо этого запустить дисковый процесс, который ранее был заблокирован в ожидании прерывания. Таким образом, прерывания больше не учитываются, а учитываются только пользовательские процессы, дисковые процессы, терминальные процессы и т. д. Эти процессы всегда блокируются во время ожидания. После считывания таких символов, как диск или ввод, процессы, ожидающие их, разблокируются и становятся запланированными для запуска.

Следующая модель представлена ​​с вышеуказанной точки зрения

Нижний уровень операционной системы — планировщик., со многими процессами на нем. Вся специфика обработки прерываний, запуска и остановки процессов скрыта в планировщике. На самом деле планировщик — это просто очень маленькая программа.

реализация процесса

Как мы упоминали ранее, для выполнения переключения между процессами операционная система поддерживает таблицу, а именно进程表(process table). Каждый процесс занимает одну запись в таблице процессов. Эта запись содержит важную информацию о состоянии процесса, включая счетчик программ, указатель стека, состояние выделения памяти, состояние открытых файлов, информацию об учетной записи и расписании, а также другую информацию, которая должна использоваться при переходе процесса из состояния выполнения в состояние готовности или блокировки. Сохранение информации, таким образом гарантируя, что процесс может быть запущен снова позже, как если бы он никогда не прерывался.

Ключевые поля в типичной системе показаны ниже.

Содержимое первого столбца такое же, как进程管理связаны, содержание второго столбца связано с存储管理связаны, содержание третьего столбца связано с文件管理Связанный.

Дополнительные сведения о текстовом сегменте, сегменте данных и сегменте стека управления хранилищем см. в следующей статье.

Язык ассемблера с твердыми базовыми знаниями, которые необходимо знать программистам (полностью)

Теперь, когда у нас есть общее представление о таблице процессов, мы можем больше рассказать об иллюзии того, как несколько последовательных процессов выполняются на одном процессоре. С каждым классом ввода-вывода связан中断向量(interrupt vector)местоположение (фиксированная область в нижней части памяти). Он содержит адрес входа процедуры обслуживания прерывания. Предполагая, что пользовательский процесс 3 выполняется, когда происходит прерывание диска, аппаратное обеспечение прерывания помещает счетчик программ, слово состояния программы, а иногда и один или несколько регистров в стек, и компьютер переходит к адресу, указанному вектором прерывания. Это то, что делает оборудование. Затем программное обеспечение берет на себя все остальное.

Все прерывания начинаются с сохранения регистров, для текущего процесса он обычно хранится в записи таблицы процессов. Впоследствии часть информации, хранимой в стеке аппаратным механизмом прерывания, удаляется из стека, а указатель стека указывает на временный стек, используемый обработчиком процесса. Некоторые операции, такие как сохранение значений регистров и установка указателя стека, не могут быть описаны на языках высокого уровня, таких как C, поэтому эти операции выполняются на коротком языке ассемблера, который обычно может использоваться всеми прерываниями, независимо от того, как вызвано прерывание, его регистр временного хранения работает одинаково.

Когда прерывание завершено, операционная система вызывает процедуру C для обработки оставшейся части прерывания. После того, как остальная часть работы выполнена, некоторые процессы готовятся, и вызывается планировщик, чтобы решить, какой процесс запустить следующим. Затем передайте управление фрагменту кода на ассемблере, загрузите значение регистра и карту памяти для текущего процесса и запустите процесс для выполнения, процесс обработки прерываний и планирования показан ниже.

  1. аппаратный счетчик программ push-стека и т. д.

  2. Аппаратное обеспечение загружает новый программный счетчик из вектора прерывания

  3. Процедура языка ассемблера сохраняет значение регистра

  4. Процедура языка ассемблера устанавливает новый стек

  5. C прерывает работу сервера (типичное чтение и кэшированная запись)

  6. Планировщик решает, какая из следующих программ будет запущена первой.

  7. Процедура C возвращается к ассемблерному коду

  8. Процесс языка ассемблера запускает новый текущий процесс

Процесс может прерываться тысячи раз во время его выполнения, но после каждого прерывания прерванный процесс возвращается в то же самое состояние, в котором он находился до прерывания.

нить

В традиционных операционных системах каждый процесс имеет адресное пространство и поток управления. Фактически, это определение большинства процессов. Однако во многих случаях обычно несколько потоков управления выполняются в одном и том же адресном пространстве, как если бы они были отдельными процессами. Теперь давайте сосредоточимся на том, что такое поток

использование нитей

Может быть, этот вопрос также является вашим вопросом. Зачем создавать концепцию потока на основе процесса? Если быть точным, это фактически обсуждение модели процесса и модели потока. Чтобы ответить на этот вопрос, вам может потребоваться ответить на него в три шага.

  • Возможность совместного использования одного и того же адресного пространства и всех доступных данных между несколькими потоками, чего нет у процессов
  • Потоки лучше, чем процессы更轻量级, так как потоки легче, их легче создавать и легче отменять, чем процессы. Во многих системах создание потока выполняется в 10-100 раз быстрее, чем создание процесса.
  • Третьей причиной может быть обсуждение производительности.Если несколько потоков интенсивно используют ЦП, то повышения производительности добиться невозможно, но если имеется много вычислений и много операций ввода-вывода, наличие нескольких потоков.Эти действия могут перекрываться. друг друга, что ускорит выполнение приложения

Многопоточное решение

Теперь рассмотрим пример использования потока: веб-сервер, запросы страниц отправляются на сервер, а запрошенные страницы отправляются обратно клиенту. На большинстве веб-сайтов одни страницы посещают больше, чем другие. Например, домашняя страница Sony имеет больше посещений, чем любая отдельная страница сведений о камере, а веб-сервер может хранить в памяти набор часто посещаемых страниц и избегать загрузки этих страниц на диск, тем самым повышая производительность. Набор таких страниц называется高速缓存(cache), кеш также используется во многих случаях, например, кеш процессора.

Выше показано, как организован веб-сервер, веб-сервер, называемый调度线程(dispatcher thread)Поток, который читает рабочий запрос из сети, после того, как поток планирования проверил запрос, выбирает бездействующий (заблокированный) рабочий поток для обработки запроса, обычно путем записи указателя на сообщение в специальное слово, связанное с каждым потоком. середина. Затем поток планирования разбудит спящий рабочий поток и изменит состояние рабочего потока с заблокированного на готовое.

Когда рабочий поток запускается, он проверяет, существует ли запрос в кэше веб-страницы, доступном для всех потоков. Если веб-страница не существует в кеше, она вызываетreadОперация извлекает страницы с диска и блокирует поток до завершения операции с диском. Когда поток блокируется при работе с диском, чтобы выполнить дополнительную работу, планирующий поток может выбрать другой поток для запуска или запустить другой готовый в данный момент рабочий поток.

Эта модель позволяет написать сервер как набор последовательных потоков с бесконечным циклом в программе, которая отправляет потоки, которая используется для получения рабочих запросов и отправки их рабочим потокам. Код для каждого рабочего потока содержит запрос, полученный от потока диспетчеризации, и проверяет, существует ли нужная страница в веб-кэше, если да, возвращает страницу непосредственно клиенту, после чего рабочий поток блокируется, ожидая нового запроса на прибыть. Если нет, рабочий поток загружает страницу с диска, возвращает страницу клиенту и блокируется в ожидании нового запроса.

Ниже приведен код для планирования потоков и рабочих потоков, предполагая, что TRUE — это константа 1, а buf и page — соответствующие структуры, содержащие рабочие запросы и веб-страницы соответственно.

Общая логика планирования потоков

while(TRUE){
  get_next_request(&buf);
  handoff_work(&buf);
}

Грубая логика рабочего потока

while(TRUE){
  wait_for_work(&buf);
  look_for_page_in_cache(&buf,&page);
  if(page_not_in_cache(&page)){
    read_page_from_disk(&buf,&page);
  }
  return _page(&page);
}

однопоточное решение

Теперь рассмотрим, как написать веб-сервер без многопоточности. Легко представить один поток, в котором основной цикл веб-сервера получает запрос и проверяет его, стремясь завершить работу до следующего запроса. В ожидании дисковых операций сервер простаивает и не обрабатывает другие входящие запросы. В результате обрабатывается очень мало запросов в секунду, поэтому этот пример показывает, что многопоточность улучшает параллелизм программы и повышает производительность программы.

Решения для конечного автомата

Пока у нас есть два решения, однопоточное решение и многопоточное решение, на самом деле есть еще одно решение, которое状态机解决方案, его процесс выглядит следующим образом

Если в данный момент доступна только неблокирующая версия системного вызова чтения, то при поступлении запроса на сервер поток единственного вызова чтения проверит, сможет ли он получить ответ из кеша, затем вернется напрямую, если нет, запустить неблокирующую дисковую операцию

Сервер записывает статус текущего запроса в таблицу, затем переходит и получает следующее событие, которое может быть запросом на новое задание или ответом диска на предыдущую операцию. Если это запрос на новую работу, то начать обработку запроса. Если это ответ от диска, соответствующая информация о состоянии берется из таблицы для обработки. Для неблокирующего дискового ввода-вывода этот ответ обычно является ответом на прерывание сигнала.

Каждый раз, когда сервер переключается из состояния, в котором запрашивается работа, в другое состояние, соответствующее вычислительное состояние должно быть явно сохранено или перезагружено. Здесь у каждого вычисления есть сохраненное состояние, и есть набор событий, которые произойдут и вызовут изменение связанного состояния.Мы называем этот тип дизайна有限状态机(finite-state machine)чашка конечного автомата широко используется в информатике.

Эти три решения имеют свои особенности: многопоточность позволяет сохранить идею последовательных процессов и добиться параллелизма, но последовательные процессы будут блокировать системные вызовы, однопоточные серверы сохраняют простоту блокирующих систем, но уступают в производительности. Подход с конечным автоматом использует неблокирующие вызовы и прерывания для достижения высокой производительности за счет параллелизма, но усложняет программирование.

Модель характеристика
один поток Отсутствие параллелизма, низкая производительность, блокировка системных вызовов
Многопоточность Имеет параллелизм, блокирует системные вызовы
Конечный автомат Параллелизм, неблокирующие системные вызовы, прерывания

Классическая резьбовая модель

Другой подход к пониманию процессов заключается в том, чтобы каким-то образом сгруппировать связанные ресурсы. Процесс имеет адресное пространство для текста программы, данных и других ресурсов. Эти ресурсы включают открытые файлы, дочерние процессы, предстоящие таймеры, обработчики сигналов, информацию об учетной записи и многое другое. Помещение этой информации в процесс легче управлять.

Другая концепция заключается в том, что у процесса есть поток выполнения, обычно обозначаемый аббревиатурой线程(thread). Поток будет иметь программный счетчик, который используется для записи следующей команды для выполнения; у потока также есть регистр, который используется для хранения переменных, которые поток использует в данный момент; у потока также есть стек, который используется для записи пути выполнения программы. Хотя поток должен выполняться в процессе, процесс и поток — это две совершенно разные концепции, и их можно обрабатывать отдельно. Процессы используются для объединения ресурсов, а потоки — это объекты, которые планируют выполнение на ЦП.

Потоки добавляют контент в модель процесса, то есть внутри одного процесса они допускают большую независимость друг от друга и не мешают друг другу. Параллельное выполнение нескольких потоков внутри процесса аналогично запуску нескольких процессов на одном компьютере. В нескольких потоках несколько потоков совместно используют одно и то же адресное пространство и другие ресурсы. Среди нескольких процессов процессы совместно используют физическую память, диски, принтеры и другие ресурсы. Поскольку поток содержит некоторые свойства процесса, поток вызывается轻量的进程(lightweight processes).多线程(multithreading)Этот термин также используется для описания нескольких потоков в одном и том же процессе.

Ниже мы видим три традиционных процесса, каждый со своим адресным пространством и одним потоком управления. Каждый поток работает в другом адресном пространстве

На рисунке ниже мы видим, что есть процесс с тремя потоками. Каждый поток работает в одном и том же адресном пространстве.

Когда несколько потоков выполняются в системе с одним процессором, потоки выполняются по очереди.В процессе описания процесса мы знаем, как работает мультипрограммирование процесса. Переключаясь между несколькими процессами, система создает иллюзию параллельного выполнения различных последовательных процессов. Аналогично работает многопоточность. Процессор переключается между потоками, и система создает иллюзию параллельного выполнения различных последовательных процессов.

Но разные потоки в процессе не обладают строгой независимостью между разными процессами. Все потоки в одном процессе будут иметь точно такое же адресное пространство, что означает, что они также используют одни и те же глобальные переменные. Поскольку каждый поток может получить доступ к каждому адресу памяти в адресном пространстве процесса,Таким образом, один поток может читать, писать и даже стирать стек другого потока.. Почему нет защиты между потоками?既不可能也没有必要. Это отличается от разных процессов.Разные процессы будут исходить от разных пользователей, и они могут быть враждебны друг другу, потому что разные процессы будут конкурировать друг с другом за ресурсы. И процесс всегда принадлежит пользователю, поэтому разработчики ОС разработали потоки, чтобы позволить имсотрудничать друг с другом, а не воевать друг с другом. В дополнение к совместному использованию одного и того же пространства памяти потоки также имеют следующее различное содержимое.

Левая часть рисунка выше — это содержимое, совместно используемое каждым потоком в одном процессе, а правая часть рисунка выше — содержимое каждого потока. Другими словами, список слева — это атрибут процесса, а список справа — это атрибут потока.

То, чего пытается достичь концепция потока, — это возможность выполнять несколько потоков, которые совместно используют набор ресурсов, чтобы эти потоки могли работать вместе для выполнения определенной задачи. Как и процессы, потоки могут находиться в следующих состояниях:Работает, блокируется, готово и прекращено (на диаграмме процесса не показано). Выполняемый поток имеет квант времени ЦП и состояние выполняется. Заблокированный поток ожидает события, которое освободит его. Например, когда поток выполняет системный вызов, который считывает данные с клавиатуры, поток блокируется до тех пор, пока не будет введена информация. Поток обычно блокируется до тех пор, пока не произойдет какое-либо внешнее событие или другой поток не освободит его.Переходы состояний между потоками аналогичны переходам состояний между процессами..

У каждого потока будет свой собственный стек, как показано на следующем рисунке.

В случае многопоточности процесс обычно начинается с текущего одиночного потока, а затем этот поток запускается вызовом библиотечной функции (такой какthread_create), чтобы создать новый поток. Функция создания потока попросит указать имя вновь созданного потока. Созданный поток обычно возвращает идентификатор потока, который является именем нового потока.

Когда поток завершил свою работу, это можно сделать, вызвав функцию (например,thread_exit) выйти. Сразу после исчезновения потока состояние становится мертвым и больше не может быть запланировано. Во время выполнения некоторых потоков это можно сделать, вызвав такие функции, какthread_join, указывая, что один поток может ожидать выхода другого потока. Этот процесс блокирует вызывающий поток до тех пор, пока он не дождется завершения указанного потока. В этом случае создание и завершение потоков очень похоже на создание и завершение процессов.

Другой общий поток вызываетthread_yield, который позволяет потоку автоматически освобождать ЦП, чтобы разрешить выполнение другого потока. Такой вызов по-прежнему важен, потому что, в отличие от процесса, поток не может использовать прерывание по часам, чтобы заставить поток уступить ЦП. Поэтому постарайтесь заставить поток вести себя高大上Некоторые из них по-прежнему более важны, и со временем потоки уступают ЦП, чтобы дать другим потокам возможность работать. Резьба принесет массу проблем и должна учитываться при проектировании комплексно.

POSIX-потоки

Чтобы сделать возможным писать переносимые многопоточные программы, IEEE определяет стандарт многопоточности в стандарте IEEE 1003.1c. Пакет потоков определяется какPthreads. Большинство систем UNIX поддерживают его. Этот стандарт определяет более 60 вызовов функций. Нецелесообразно перечислять их все. Вот некоторые наиболее часто используемые системные вызовы.

POSIX-потоки(часто называютpthreads) — это независимая от языка модель выполнения, а также модель параллельного выполнения. Это позволяет программе управлять несколькими различными рабочими процессами, которые перекрываются во времени. Каждый рабочий процесс называется потоком, и эти процессы можно создавать и контролировать, вызывая API потоков POSIX. Его можно понимать как стандарт для потоков.

Реализации потоков POSIX доступны во многих аналогичных и совместимых с POSIX операционных системах, например.FreeBSD, NetBSD, OpenBSD, Linux, macOS, Android, Solaris, реализованный поверх существующего Windows API.pthread.

IEEE — крупнейшая в мире техническая профессиональная организация, занимающаяся развитием технологий на благо человечества.

вызов потока описывать
pthread_create создать новую тему
pthread_exit завершить вызывающий поток
pthread_join дождитесь выхода определенного потока
pthread_yield Освободить ЦП для запуска другого потока
pthread_attr_init Создание и инициализация структуры свойств потока
pthread_attr_destory удалить структуру атрибутов потока

Все Pthreads имеют определенные свойства, каждое из которых содержит идентификатор, набор регистров (включая программный счетчик) и набор свойств, хранящихся в структуре. Это свойство включает размер стека, параметры планирования и другие элементы, требуемые потоком.

Новая нить пройдетpthread_createCreate, в качестве значения функции возвращается идентификатор вновь созданного потока. Этот вызов очень похож на UNIX.forkсистемные вызовы (помимо аргументов), где играет идентификатор потокаPIDЦель этого состоит в том, чтобы отличить его от других потоков.

Когда поток завершит назначенную ему работу, он пройдетpthread_exitпрекратить. Этот вызов останавливает поток и освобождает стек.

Обычно поток должен дождаться, пока другой поток завершит свою работу и завершит свою работу, прежде чем продолжить. в состоянии пройтиpthread_joinВызывается потоком для ожидания завершения другого конкретного потока. И идентификатор потока, который нужно ожидать, задается в качестве параметра.

Иногда случается, что поток логически не блокируется, но кажется, что он работает достаточно долго и хочет дать шанс запуститься другому потоку. В это время можно пройтиpthread_yieldЧто нужно сделать.

Следующие два вызова потока имеют дело со свойствами.pthread_attr_initСоздает структуру свойств, связанную с потоком, и инициализирует ее значениями по умолчанию.Эти значения (например, приоритет) можно изменить, изменив значение структуры свойств.

наконец-то,pthread_attr_destroyУдаляет структуру потока, освобождая занимаемую ею память. Это не влияет на поток, который его вызывает, эти потоки живут вечно.

Чтобы лучше понять, как работают потоки, рассмотрим следующий пример.

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NUMBER_OF_THREADS 10

void *print_hello_world(vvoid *tid){
  /* 输出线程的标识符,然后退出 */
  printf("Hello World. Greetings from thread %d\n",tid);
  pthread_exit(NULL);
}

int main(int argc,char *argv[]){
  /* 主程序创建 10 个线程,然后退出 */
  pthread_t threads[NUMBER_OF_THREADS];
  int status,i;
 	
  for(int i = 0;i < NUMBER_OF_THREADS;i++){
    printf("Main here. Creating thread %d\n",i);
    status = pthread_create(&threads[i], NULL, print_hello_world, (void *)i);
    
    if(status != 0){
      printf("Oops. pthread_create returned error code %d\n",status);
      exit(-1);
    }
  }
  exit(NULL);
}

Основная нить, объявив свое обвинение, зацикливаетсяNUMBER_OF_THREADSраз, каждый раз, когда создается новый поток. Если создание потока завершится ошибкой, он напечатает сообщение и завершит работу. После создания всей работы основная программа завершает работу.

реализация потока

Существует три основных реализации: одна предназначена для реализации потоков в пространстве пользователя, другая — для реализации потоков в пространстве ядра, а третья — для смешивания потоков в пространстве пользователя и ядра. давайте обсудим отдельно

Реализация потоков в пользовательском пространстве

Первый способ — поместить весь пакет потоков в пользовательское пространство, ядро ​​ничего не знает о потоках, оно не знает о существовании потоков. Все такие реализации имеют одинаковую общую структуру

Потоки выполняются поверх системы выполнения, которая представляет собой набор процессов, управляющих потоками, включая четыре упомянутых ранее: pthread_create, pthread_exit, pthread_join и pthread_yield.

运行时系统(Runtime System)Также называемая средой выполнения, система выполнения обеспечивает среду, в которой выполняются программы. Эта среда может решить многие проблемы, в том числе структуру памяти приложения, способ доступа программы к переменным, механизм передачи параметров между процедурами, интерфейс с операционной системой и многое другое. Компилятор делает предположения для создания правильного кода на основе конкретной системы времени выполнения. Как правило, система выполнения отвечает за настройку и управление стеком и включает в себя такие вещи, как сборка мусора, многопоточность или другие динамические функции, встроенные в язык.

При управлении потоками в пользовательском пространстве каждый процесс должен иметь свой собственный выделенный поток.线程表(thread table), используемый для отслеживания потоков в процессе. Эти таблицы аналогичны таблицам процессов в ядре, но в них записываются только свойства отдельных потоков, такие как программный счетчик каждого потока, указатель стека, регистры и состояние. Метка резьбы единообразно управляется системой выполнения. Когда поток переходит в состояние готовности или блокировки, вся информация для перезапуска потока сохраняется в таблице потоков точно так же, как информация, хранящаяся ядром в таблице процессов.

Преимущества реализации потоков в пользовательском пространстве

Реализация потоков в пространстве пользователя имеет следующие преимущества по сравнению с реализацией потоков в пространстве ядра: подумайте, завершается ли поток или когда вызовpthread_yieldПри необходимости поток процесса будет переключаться, а затем информация о потоке будет сохранена в таблице потоков, предоставленной средой выполнения, а затем планировщик потоков выберет другой поток для запуска. Сохранение состояния потока и планировщик являются локальными процедурами, поэтому их запуск более эффективен, чем вызов ядра. Следовательно, нет необходимости в ловушке в ядре, поэтому нет необходимости в переключении контекста, и нет необходимости очищать кеш памяти, потому что планирование потоков очень удобно, поэтому эффективность относительно высока.

Еще одним преимуществом реализации потоков в пользовательском пространстве является то, что каждый процесс может иметь свой собственный алгоритм планирования. Например, в некоторых приложениях те, у кого есть потоки сборки мусора (вы знаете, кто), не должны беспокоиться о том, что их потоки остановятся в неподходящее время, что является преимуществом. Пользовательские потоки также имеют лучшую масштабируемость, потому что потоки ядра в пространстве ядра требуют некоторого табличного пространства и пространства стека.Если число потоков ядра относительно велико, легко вызвать проблемы.

Недостатки реализации потоков в пользовательском пространстве

Хотя реализация потоков в пользовательском пространстве будет иметь определенные преимущества в производительности, недостатки по-прежнему очевидны.阻塞系统调用Шерстяная ткань? Предполагая, что поток считывает клавиатуру до того, как будет выполнен какой-либо ввод с клавиатуры, невозможно заставить поток выполнять системный вызов, потому что это остановит все потоки. так,Одна из целей использования потоков — иметь возможность выполнять блокирующие вызовы из потоков и избегать влияния блокирующих потоков на другие потоки..

Аналогичная проблема с блокировкой звонков есть缺页中断Проблема, собственно, в том, что компьютер не помещает все программы в память одновременно.Если в программе происходит вызов функции или инструкция перехода к инструкции, которой нет в памяти, то произойдет ошибка страницы, и операционная система восстановит потерянную инструкцию с диска, которая называется缺页故障. Когда требуемые инструкции будут прочитаны и выполнены, соответствующий процесс будет заблокирован. Если только один поток вызывает страничную ошибку, ядро, поскольку оно даже не знает о существовании потока, обычно блокирует весь процесс до тех пор, пока дисковый ввод-вывод не завершится, даже если другие потоки могут работать.

Другая проблема с реализацией потоков в пользовательском пространстве заключается в том, что если поток начинает выполняться, никакие другие потоки в процессе этого потока не могут выполняться, если только первый поток добровольно не освобождает ЦП.Внутри одного процесса нет прерывания по часам, поэтому невозможно планировать потоки с использованием циклического планирования. Нет никаких шансов, что планировщик сможет запланировать поток, если другие потоки не могут войти в среду выполнения по своей собственной воле.

Реализовать потоки в ядре

Теперь мы рассмотрим случай использования ядра для реализации потоков, после чего среда выполнения больше не нужна. Кроме того, для каждого процесса нет таблицы потоков. Вместо этого в ядре есть таблица потоков, которая отслеживает все потоки в системе. Когда поток хочет создать новый поток или отменить существующий поток, он выполняет системный вызов, который завершает работу по созданию или уничтожению потока, обновляя таблицу потоков.

Таблица потоков в ядре содержит регистры, статус и другую информацию для каждого потока. Эта информация такая же, как информация о потоке в пользовательском пространстве, но расположение размещается в ядре, а не в пользовательском пространстве. Кроме того, ядро ​​поддерживает таблицу процессов для отслеживания состояния системы.

Все блокирующие вызовы реализованы как системные вызовы.Когда поток заблокирован, ядро ​​может выбрать, запускать ли другой поток в том же процессе (если есть готовый поток) или запускать в другом процессе. Но в пользовательской реализации исполняющая система всегда запускает свои собственные потоки до тех пор, пока ядро ​​не лишит ее кванта процессорного времени (или пока не перестанут выполняться потоки).

Из-за больших накладных расходов на создание или уничтожение потоков в ядре некоторые системы используют метод повторного использования потоков для повторного использования. Когда поток разрушается, он помечается как неработоспособный, но его внутренняя структура не затрагивается. Позже, когда необходимо создать новый поток, старый поток снова включается, помечая его как доступный. На самом деле потоки также могут быть переработаны в пользовательском пространстве, но, поскольку накладные расходы на создание или уничтожение потоков в пользовательском пространстве невелики, в этом нет необходимости.

Если поток в процессе вызывает отказ страницы, ядро ​​может легко проверить, есть ли другие потоки, которые могут быть запущены. Недостатком этого является то, что стоимость системных вызовов относительно высока, поэтому при наличии большого количества операций с потоками (создание, завершение) это принесет много накладных расходов.

Гибридная реализация

Сочетая преимущества пользовательского пространства и пространства ядра, разработчики приняли内核级线程метод, а затем мультиплексировать потоки пользовательского уровня с некоторыми или всеми потоками ядра.

В этой модели программисты могут свободно управлять количеством пользовательских потоков и потоков ядра с большой гибкостью. При таком подходе ядро ​​идентифицирует и планирует только потоки уровня ядра. Некоторые из этих потоков уровня ядра мультиплексируются несколькими потоками уровня пользователя.

Суммировать

В этой статье рассказывается об уровне операционной системы, что такое процесс и поток? Описана разница между моделью процесса и моделью потока, состояние процесса и потока, иерархическая структура и многие другие технические термины.

В следующей статье мы рассмотрим, как взаимодействуют процессы, а такжеОсновной принцип многопоточности на уровне операционной системы, Следите за обновлениями.

Ссылка на статью:

«Современные операционные системы».

《Современная операционная система》четвертое издание

woohoo.encyclopedia.com/computing/you…

Всего 00 лайков .VE series rogue.org/sys call/ в тот день…

woohoo.bottom upparameters.com/process_or т.е...

En. Wikipedia.org/wiki/run Тим…

Итак, Wikipedia.org/wiki/exe вырезать…