Что такое процесс и нить? - PullRequest
51 голосов
/ 23 февраля 2010

Да, я прочитал много материалов, связанных с операционной системой. И я все еще читаю. Но, похоже, что все они описывают процесс и поток «абстрактно», что вызывает много поводов для высокого уровня их поведения и логической организации. Мне интересно, что они физически ? По-моему, это всего лишь некоторые "структуры данных" в памяти, которые поддерживаются и используются кодами ядра для облегчения выполнения программы. , Например, операционная система использует некоторую структуру данных процесса (PCB) , чтобы описать аспекты процесса, назначенного для определенной программы, такие как его приоритет, его адресное пространство и так далее. Это все в порядке?

Ответы [ 22 ]

29 голосов
/ 23 февраля 2010

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

Итак, что это за нить? Самое близкое, что я могу объяснить, это состояние выполнения , как в: комбинации регистров ЦП, стека, лота. Вы можете убедиться в этом, взломав отладчик на любой данный момент. Что ты видишь? Стек вызовов, набор регистров. Вот и все. Это нить.

Теперь, что такое процесс? Ну, это как абстрактная сущность «контейнер» для запуска потоков. Что касается ОС в первом приближении, то это сущность, которой ОС выделяет несколько ВМ, назначает системные ресурсы (например, файловые дескрипторы, сетевые сокеты) и т. Д.

Как они работают вместе? ОС создает «процесс», резервируя для него некоторые ресурсы и запуская «основной» поток. Этот поток может порождать больше потоков. Это потоки в одном процессе. Они более или менее могут совместно использовать эти ресурсы (скажем, для них может потребоваться блокировка, чтобы не испортить удовольствие для других и т. Д.). С этого момента ОС обычно отвечает за поддержание этих потоков «внутри» этой виртуальной машины (обнаружение и предотвращение попыток доступа к памяти, которая не «принадлежит» этому процессу), обеспечивая некоторый тип планирования этих потоков, чтобы они могли работать "один-после-другому-и-не-только-один-все-в-времени".

28 голосов
/ 23 февраля 2010

Обычно при запуске такого исполняемого файла, как notepad.exe, создается один процесс. Эти процессы могут порождать другие процессы, но в большинстве случаев для каждого исполняемого файла, который вы запускаете, существует отдельный процесс. Внутри процесса может быть много потоков. Обычно сначала существует один поток, который обычно запускается в «точке входа» программ, обычно это функция main. Инструкции выполняются одна за другой по порядку, как у человека, у которого только одна рука, поток может делать только одну вещь за один раз, прежде чем перейти к следующей.

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

Это довольно упрощенное объяснение. Я мог бы углубиться в детали, но, вероятно, совпадать с тем, что вы найдете в своих учебниках.

РЕДАКТИРОВАТЬ: вы заметите, что в моем объяснении много «обычно», поскольку есть редкие программы, которые делают вещи кардинально иные.

10 голосов
/ 23 февраля 2010

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

Их конкретные реализации отличаются чрезвычайно .

Сравните, например, процесс Эрланга и процесс Windows: процесс Эрланга очень легкий, часто менее 400 байт. Вы можете без проблем запустить 10 миллионов процессов на не очень новом ноутбуке. Они запускаются очень быстро, они умирают очень быстро, и ожидается, что вы сможете использовать их для очень коротких задач. Каждый процесс Erlang имеет свой собственный сборщик мусора, связанный с ним. Процессы Эрланга никогда не могут совместно использовать память.

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

Потоки похожи: нить Linux NPTL на x86 может быть размером до 4 Кбайт, и с некоторыми приемами вы можете запустить 800000+ на 32-битной машине x86. Машина, безусловно, будет использоваться с тысячами, может быть, десятками тысяч нитей. Поток .NET CLR имеет минимальный размер около 1 МБ, что означает, что только 4000 из них будут использовать все ваше адресное пространство на 32-разрядной машине. Таким образом, хотя 4000 NPTL Linux Threads обычно не являются проблемой, вы даже не можете запустить 4000 .NET CLR Threads, потому что до этого у вас не хватит памяти.

Процессы ОС и потоки ОС также очень по-разному реализованы в разных операционных системах. Основные два подхода: ядро ​​знает только о процессах. Потоки реализуются библиотекой Userspace без какого-либо знания ядра вообще. В этом случае снова есть два подхода: 1: 1 (каждый поток отображается на один процесс ядра) или m: n (m потоков отображается на n процессов, где обычно m> n и часто n == #CPU). Это был ранний подход, принятый во многих операционных системах после изобретения потоков. Однако обычно он считается неэффективным и заменяется почти во всех системах вторым подходом: потоки реализованы (по крайней мере, частично) в ядре, так что ядро ​​теперь знает о двух различных сущностях, потоках и процессах.

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

В зависимости от того, как вы устанавливаете эти флаги, вы получаете либо поток (общий доступ ко всему), либо процесс (общий доступ ко всем системным ресурсам, таким как системные часы, пространство имен файловой системы, пространство имен сети, пространство имен идентификатора пользователя, процесс ID пространства имен, но не делят адресное пространство). Но вы также можете получить и другие довольно интересные вещи. Вы можете тривиально получить тюрьмы в стиле BSD (в основном те же флаги, что и у процесса, но не разделяйте файловую систему или сетевое пространство имен). Или вы можете получить то, что другие ОС называют Контейнером или Зоной виртуализации (например, тюрьмой, но не разделяйте пространства имен UID и PID и системные часы). Еще пару лет назад с помощью технологии KVM (виртуальная машина ядра) вы даже можете получить полноценную виртуальную машину (не делиться ничем, даже таблицами страниц процессора). [Крутая вещь в этом заключается в том, что вы можете повторно использовать тщательно настроенный зрелый планировщик задач в ядре для всех этих вещей. Виртуальная машина Xen часто критиковалась за низкую производительность планировщика. Разработчики KVM имеют гораздо лучший планировщик, чем Xen, и самое лучшее, что им даже не нужно было писать для него ни одной строчки кода!]

Итак, в Linux производительность потоков и процессов намного ниже, чем в Windows и многих других системах, потому что в Linux они на самом деле одно и то же. Это означает, что шаблоны использования очень разные: в Windows вы обычно выбираете между использованием потока и процесса в зависимости от их веса: могу ли я позволить себе процесс или использовать поток, даже если я на самом деле не хочу делиться государство? В Linux (и обычно в Unix в целом) вы решаете, основываясь на их семантике: я действительно хочу поделиться состоянием или нет?

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

В Windows потоки являются основными единицами параллелизма, а компоненты COM или объекты .NET являются основными единицами функциональности. Приложения обычно состоят из одного длительного процесса.

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

Практически единственное, что вы можете сказать о потоках и процессах, это:

  • Потоки принадлежат процессам
  • Нити легче, чем процессы
  • Потоки делят большинство состояний друг с другом
  • Процессы имеют значительно меньшее состояние, чем потоки (в частности, они обычно не разделяют память, если специально не запрошено)
7 голосов
/ 23 февраля 2010

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

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

7 голосов
/ 23 февраля 2010

Я бы сказал, что:

У процесса есть область памяти, открытые файлы, ... и один или несколько потоков.

Поток - это поток команд, который может планироваться системой на процессоре.

5 голосов
/ 23 февраля 2010

Мы обсуждали эту проблему несколько раз здесь. Возможно, вы найдете здесь полезную информацию:

В чем разница между процессом и потоком

Процесс против резьбы

Нить и обработка

4 голосов
/ 23 февраля 2010

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

Процесс включает в себя следующее:

  • Частное виртуальное адресное пространство
  • Программа.
  • Список ручек.
  • Токен доступа.
  • Уникальный идентификатор процесса.
  • хотя бы одна нить.
  • Указатель на родительский процесс, независимо от того, существует этот процесс или нет.

При этом процесс может содержать несколько потоков.

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

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

У меня есть пара страниц в моей вики, на которые вы можете посмотреть:

Процесс

Тема

3 голосов
/ 23 февраля 2010

Физически:

  • Процесс - это структура, которая поддерживает учетные данные владельца, список потоков и список открытых дескрипторов

  • Поток - это структура, содержащая контекст (т. Е. Сохраненный набор регистров + место для выполнения), набор PTE, описывающих, какие страницы отображаются в пространство виртуальных адресов процесса, и владелец

Это, конечно, чрезвычайно упрощенное объяснение, но оно получает важные сведения. Фундаментальной единицей выполнения в Linux и Windows является Thread - планировщик ядра не заботится о процессах (сильно). Вот почему в Linux поток - это просто процесс, который обменивается PTE с другим процессом.

3 голосов
/ 23 февраля 2010

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

2 голосов
/ 23 февраля 2010

Трудно дать короткий ответ, который справедливо отвечает на этот вопрос.

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

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

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

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

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

С другой стороны, упреждение всего процесса обходится дороже, чем вы можете себе представить.

Редактировать: Идеи применимы и к абстрактным платформам, таким как Java.

...