Поток и процессы в операционной системе, процессоре и программировании
Поток, процесс, задача, операционная систем а , программа, программировани е — это все звенья одной системы. Что такое потоки в процессоре? Что такое процесс в программировании? Что такое потоки и процессы в операционной системе? Эти и другие вопросы часто ставят врасплох начинающих программистов. Во всех этих определениях можно не запутаться, если понимать , о чем и дет речь. Сегодня в стать е м ы разложим все «по полкам» простым и понятным языком.
Процессы и потоки в операционной систем е ( ОС)
- оперативная память;
- время процессоров.
Что такое потоки в операционной системе и процессоре
Мы выяснили, что процесс в операционной системе является неким объектом, которому выделяются системные ресурсы, но самостоятельно он не выполняет код программы. У одного процесса мо жет быть несколько потоков, которые будут выполняться одновременно и параллельно. Важно отметить, что несколько потоков одного процесса будут выполнять отдельные части кода одной программы.
Объясним просто. Когда на компьютере запущено несколько разных приложени й , тогда мы можем считать, что запущено несколько разных процессов. Когда мы запускаем одно приложение на компьютере и внутри него выполняем несколько разных действий, то мы можем предполагать, что они выполняются в разных потоках, но в одном процессе. Например, вы запустили текстовый редактор, тогда запись текста, автоматическое сохранение, проверка орфографии и т. д. могут быть разными потоками одного приложения.
Представим на секунду, сколько процессов может быть одновременно запущено на компьютере? Несколько десятков. А сколько потоков могут быть одновременно запущены на компьютере? Несколько сотен. Установленный процессор чисто физически не справился бы со всеми потоками одновременно. Поэтому в операционной системе существует специальный планировщик процессорных потоков. Суть его работы сводится к тому, чтобы выдавать приоритет каждому отдельному потоку и отправлять на выполнение тот, у которого максимальный приоритет.
Например, у вас запущен браузер, мессенджер и текстовый редактор на компьютере. Пока вы ищите информацию в браузере , все его потоки будут задействованы, однако потоки мессенджера и редактора будут «приторможены», потому что вы не пользуетесь этими приложениями в данный момент времени. Вы нашли в браузере информацию и решили записать ее в редактор. В этот момент часть потоков браузера «притормаживается», но активируются потоки редактора, а потоки мессенджера пока «спят». Вы пишите в редакторе , и вам приходит сообщение в мессенд жер . Вы открываете мессенджер, чтобы ответить. В этот момент потоки браузера и редактора «притормаживаются», но активизируются потоки мессенджера. Здесь принцип распределения потоков описан очень просто , с упущением многих моментов, однако суть распределения изложена верно. Операционная система активирует тот поток, исполнение которого необходимо пользователю в данный момент времени , и останавливает те потоки, которые пользователю пока не нужны.
Получается, что приори те тность потоков является условным свойством, которое может быть передано любому потоку, если пользователю или устройству необходимо его исполнение.
Что такое потоки в процессоре
- один с 4 ядрами по 2 потока, то есть всего 8 потоков;
- второй с 8 яд рами по одному потоку, то есть тоже 8 потоков.
Заключение
Что такое потоки в процессоре? Это «каналы» для одновременного исполнения команд. Чем больше потоков, тем больше команд может обработать процессор, а значит , многопоточная программа будет работать быстрее.
Что такое процесс в ОС? Простыми словами, процессом в операционной системе является каждое отдельно запущенное приложение. Процессы в ОС не взаимосвязаны, поэтому могут работать по отдельности.
Что такое поток в программировании? Это возможность разрабатываемой программы работать параллельно в несколько «веток » ( потоков). Потоки в программировании взаимосвязаны. Потоки одной программы не могут работать отдельно друг от друга.
Потоки, процессы, задачи являются очень интересной и обширной темой. Сегодня мы лишь приоткрыли занавес по этой тематике, чтобы вы имели представлени е об этих терминах.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
В чем разница между процессом и потоком?
У меня такое ощущение, что слово «процесс» используется слишком часто, и есть также аппаратные и программные потоки. Как насчет легких процессов в таких языках, как Erlang ? Есть ли определенная причина использовать один термин над другим?
Вероятно, стоит сказать, что у каждой ОС есть свое представление о том, что такое «поток» или «процесс». Некоторые основные ОС «не имеют понятия« поток », есть также некоторые встроенные ОС», которые имеют только «потоки».
И процессы, и потоки являются независимыми последовательностями выполнения. Типичное различие заключается в том, что потоки (одного и того же процесса) работают в общем пространстве памяти, а процессы — в отдельных пространствах памяти.
Я не уверен, на какие «аппаратные» и «программные» темы вы могли ссылаться. Потоки — это функция операционной среды, а не функция ЦП (хотя ЦП обычно выполняет операции, которые делают потоки эффективными).
Эрланг использует термин «процесс», потому что он не раскрывает модель многопрограммирования с общей памятью. Называя их «потоками», можно предположить, что они имеют общую память.
Аппаратные потоки, вероятно, ссылаются на контексты нескольких потоков внутри ядра (например, HyperThreading, SMT, Sun’s Niagara / Rock). Это означает дублирование файлов регистра, дополнительные биты, переносимые с инструкцией по конвейерам, и более сложную логику обхода / пересылки, среди прочего.
@greg, одно сомнение у меня в темах. позвольте мне рассмотреть, у меня есть процесс A, который получил некоторое пространство в оперативной памяти. Если процесс A создает поток, поток также должен иметь некоторое пространство для выполнения. Так увеличит ли это размер пространства, созданного для процесса А, или пространство для потока, созданного где-то еще? Так что же создает этот процесс в виртуальном пространстве? Пожалуйста, поправьте меня, если мой вопрос неправильный. Спасибо
@JeshwanthKumarNK: при создании нового потока выделяется как минимум достаточно памяти для нового стека. Эта память выделяется ОС в процессе А.
Этот ответ кажется неправильным. Если бы оба процесса и потоки были независимыми последовательностями выполнения, то процесс, который содержал два потока, должен был бы иметь три последовательности выполнения, и это не может быть правильным. Только поток является последовательностью выполнения — процесс — это контейнер, который может содержать одну или несколько последовательностей выполнения.
«Аппаратные потоки» — это потоки, которым предоставляются отдельные аппаратные ресурсы (отдельное ядро, процессор или гиперпотоки). «Программные потоки» — это потоки, которые должны конкурировать за одинаковую вычислительную мощность.
Процесс
Каждый процесс предоставляет ресурсы, необходимые для выполнения программы. Процесс имеет виртуальное адресное пространство, исполняемый код, открытые дескрипторы для системных объектов, контекст безопасности, уникальный идентификатор процесса, переменные среды, класс приоритета, минимальный и максимальный размеры рабочего набора и, по крайней мере, один поток выполнения. Каждый процесс запускается с одного потока, часто называемого основным потоком, но может создавать дополнительные потоки из любого его потока.
Поток
Поток — это объект внутри процесса, который можно запланировать для выполнения. Все потоки процесса совместно используют его виртуальное адресное пространство и системные ресурсы. Кроме того, каждый поток поддерживает обработчики исключений, приоритет планирования, локальное хранилище потока, уникальный идентификатор потока и набор структур, которые система будет использовать для сохранения контекста потока до его планирования. Контекст потока включает в себя набор машинных регистров потока, стек ядра, блок среды потока и пользовательский стек в адресном пространстве процесса потока. Потоки также могут иметь собственный контекст безопасности, который можно использовать для олицетворения клиентов.
Эта информация была найдена в Документах Microsoft здесь: О процессах и потоках
Microsoft Windows поддерживает вытесняющую многозадачность, которая создает эффект одновременного выполнения нескольких потоков из нескольких процессов. На многопроцессорном компьютере система может одновременно выполнять столько потоков, сколько имеется процессоров на компьютере.
Для людей, которые хотят знать, почему вы не можете одновременно отформатировать дискету: stackoverflow.com/questions/20708707/…
@LuisVasconcellos — если бы не было потоков, то процесс ничего бы не сделал. В процессе будет загружен только некоторый код и состояние программы. Это не очень полезно. Это было бы похоже на дорогу без транспортных средств по ней.
@LuisVasconcellos — Хорошо. Да, вы можете думать о потоке как о чем-то, что проходит через код процесса и выполняет инструкции в этом коде.
Этот ответ намного лучше, чем принятый ответ, потому что он говорит об идеале процессов и потоков: они должны быть отдельными вещами с отдельными проблемами. Дело в том, что большинство операционных систем имеют историю, уходящую гораздо дальше, чем изобретение потоков, и, следовательно, в большинстве операционных систем эти проблемы все еще несколько запутаны, даже если они постепенно улучшаются со временем.
@BKSpurgeon С каждым объяснением вы должны поднять своего читателя с одного уровня понимания на следующий. К сожалению, я не могу адаптировать ответ для каждого читателя и поэтому должен принять уровень знаний. Для тех, кто не знает, они могут продолжить поиск терминов, которые я использую, они не понимают, не так ли, пока они не достигнут базовой точки, которую они действительно понимают. Я собирался предложить вам свой ответ, но рад видеть, что вы уже получили.
Обработать:
- Исполняемый экземпляр программы называется процессом.
- Некоторые операционные системы используют термин «задача» для обозначения выполняемой программы.
- Процесс всегда сохраняется в основной памяти, также называемой основной памятью или оперативной памятью.
- Следовательно, процесс называется активным субъектом. Исчезает, если машина перезагружена.
- Несколько процессов могут быть связаны с одной и той же программой.
- В многопроцессорной системе несколько процессов могут выполняться параллельно.
- В однопроцессорной системе, хотя истинный параллелизм не достигается, применяется алгоритм планирования процессов, и процессор планирует выполнять каждый процесс по одному, создавая иллюзию параллелизма.
- Пример: выполнение нескольких экземпляров программы «Калькулятор». Каждый из экземпляров называется процессом.
Нить:
- Поток — это подмножество процесса.
- Он называется «облегченным процессом», поскольку он похож на реальный процесс, но выполняется в контексте процесса и использует те же ресурсы, которые выделены для процесса ядром.
- Обычно процесс имеет только один поток управления — один набор машинных инструкций, выполняемых одновременно.
- Процесс также может состоять из нескольких потоков выполнения, которые выполняют инструкции одновременно.
- Несколько потоков управления могут использовать истинный параллелизм, возможный в многопроцессорных системах.
- В однопроцессорной системе применяется алгоритм планирования потоков, и процессор планирует запускать каждый поток по одному.
- Все потоки, запущенные внутри процесса, имеют одинаковое адресное пространство, дескрипторы файлов, стек и другие атрибуты, связанные с процессом.
- Поскольку потоки процесса совместно используют одну и ту же память, синхронизация доступа к общим данным внутри процесса приобретает беспрецедентную важность.
Я позаимствовал вышеупомянутую информацию из Quest Knowledge! блог .
Кумар: Насколько мне известно, потоки не разделяют один и тот же стек. В противном случае было бы невозможно запустить разные коды для каждого из них.
Да, я думаю, что @MihaiNeacsu прав. Потоки совместно используют «код, данные и файлы» и имеют свои собственные «регистры и стек». Слайд из моего курса по ОС: i.imgur.com/Iq1Qprv.png
Это весьма полезно, поскольку в нем подробно рассматриваются, что такое потоки и процессы и как они связаны друг с другом. Я бы предложил добавить пример потока, тем более, что есть один для процесса. Хорошая вещь!
Kquest.co.cc ссылки не работают.
@ Rndp13 Проблема заключается только в использовании слова «стек», а не «стеки». Потоки делят стеки, так как стек является лишь частью виртуальной памяти, а потоки разделяют всю виртуальную память. Потоки могут даже хранить свои указатели стека, и выполнение может быть возобновлено другим потоком без проблем. То, что один поток выполняет один стек в одно конкретное время, не означает, что потоки не совместно используют стеки, как тот факт, что один поток одновременно работает с файловым дескриптором, не означает, что потоки не совместно используют файловые дескрипторы. ,
Сначала давайте посмотрим на теоретический аспект. Вам необходимо понять, что такое концептуально процесс, чтобы понять разницу между процессом и потоком и тем, что между ними.
У нас есть следующее из раздела 2.2.2 Модель классической резьбы в современных операционных системах 3e от Tanenbaum:
Модель процесса основана на двух независимых концепциях: группировка ресурсов и выполнение. Иногда полезно разделить их; это где темы приходят .
Один из способов взглянуть на процесс состоит в том, что это способ объединить связанные ресурсы. Процесс имеет адресное пространство, содержащее текст и данные программы, а также другие ресурсы. Эти ресурсы могут включать открытые файлы, дочерние процессы, ожидающие тревоги, обработчики сигналов, учетную информацию и многое другое. Объединяя их в форме процесса, ими можно легче управлять. Другая концепция, которую имеет процесс, — это поток выполнения, обычно сокращаемый до простого потока. Поток имеет программный счетчик, который отслеживает, какую инструкцию выполнять дальше. Он имеет регистры, в которых хранятся текущие рабочие переменные. Он имеет стек, который содержит историю выполнения, с одним кадром для каждой вызванной процедуры, но еще не возвращенной из. Хотя поток должен выполняться в каком-то процессе, нить и ее процесс являются разными понятиями и могут рассматриваться отдельно. Процессы используются для группировки ресурсов; потоки — это объекты, запланированные для выполнения на процессоре.
Далее он предоставляет следующую таблицу:
Per process items | Per thread items ------------------------------|----------------- Address space | Program counter Global variables | Registers Open files | Stack Child processes | State Pending alarms | Signals and signal handlers | Accounting information |
Давайте разберемся с проблемой аппаратного многопоточности . Классически, ЦП будет поддерживать один поток выполнения, поддерживая состояние потока с помощью одного счетчика программы и набора регистров. Но что произойдет, если пропадет кеш? Извлечение данных из основной памяти занимает много времени, и пока это происходит, процессор просто бездействует. Таким образом, у кого-то возникла идея в основном иметь два набора состояний потока (ПК + регистры), чтобы другой поток (может быть, в том же процессе, может быть, в другом процессе) мог выполнить работу, пока другой поток ожидает в основной памяти. Существует несколько имен и реализаций этой концепции, таких как HyperThreading и одновременное многопоточность (для краткости SMT).
Теперь давайте посмотрим на сторону программного обеспечения. Есть три основных способа реализации потоков на стороне программного обеспечения.
- Темы в пользовательском пространстве
- Потоки ядра
- Сочетание двух
Все, что вам нужно для реализации потоков, — это возможность сохранять состояние процессора и поддерживать несколько стеков, что во многих случаях может быть сделано в пространстве пользователя. Преимущество потоков в пользовательском пространстве заключается в супер-быстром переключении потоков, поскольку вам не нужно захватывать ядро и возможность планировать свои потоки так, как вам нравится. Самым большим недостатком является невозможность блокировать ввод-вывод (который блокировал бы весь процесс и все его пользовательские потоки), что является одной из основных причин, по которым мы используем потоки в первую очередь. Блокировка ввода / вывода с использованием потоков во многих случаях значительно упрощает разработку программы.
Преимущество потоков ядра в том, что они могут использовать блокирующий ввод / вывод, в дополнение к тому, что все проблемы с планированием оставлены для ОС. Но каждое переключение потоков требует захвата в ядро, которое потенциально относительно медленное. Однако, если вы переключаете потоки из-за заблокированного ввода-вывода, это на самом деле не проблема, поскольку операция ввода-вывода, вероятно, в любом случае заманила вас в ядро.
Другой подход заключается в объединении двух потоков с несколькими потоками ядра, каждый из которых имеет несколько пользовательских потоков.
Итак, возвращаясь к вашему вопросу о терминологии, вы можете увидеть, что процесс и поток выполнения — это две разные концепции, и выбор того, какой термин использовать, зависит от того, о чем вы говорите. Что касается термина «облегченный процесс», я лично не вижу в этом смысла, поскольку он на самом деле не передает происходящего, а также термин «поток исполнения».
Отличный ответ! Это ломает много жаргона и предположений. Это делает эту строку неуклюжей, хотя: «Итак, у кого-то возникла идея иметь два набора состояний потоков (ПК + регистры)» — о чем здесь упоминается «ПК»?
@Smithers ПК — это программный счетчик или указатель команд, который дает адрес следующей команды, которая должна быть выполнена: en.wikipedia.org/wiki/Program_counter
Я вижу что ты тут делал. stackoverflow.com/questions/1762418/process-vs-thread/…
Почему «Стек» не указан в разделе «Для элементов процесса»? Оба процесса и потоки имеют свой собственный стек.
@ stackoverflowuser2010 не только потоки имеют стеки. То, что вы называете процессом, — это процесс с одним потоком выполнения, и этот поток имеет стек, а не процесс.
Чтобы объяснить больше в отношении параллельного программирования
- Процесс имеет автономную среду выполнения. Процесс обычно имеет полный, частный набор основных ресурсов времени выполнения; в частности, каждый процесс имеет свое собственное пространство памяти.
- Внутри процесса существуют потоки — у каждого процесса есть хотя бы один. Потоки совместно используют ресурсы процесса, включая память и открытые файлы. Это способствует эффективному, но потенциально проблематичному общению.
Помня среднего человека,
На вашем компьютере откройте Microsoft Word и веб-браузер. Мы называем эти два процесса .
В Microsoft Word вы вводите какую-то вещь, и она автоматически сохраняется. Теперь вы бы заметили, что редактирование и сохранение происходит параллельно — редактирование в одном потоке и сохранение в другом.
Отличный ответ, он делает вещи простыми и предоставляет пример, к которому может относиться каждый пользователь, даже просматривающий вопрос.
Разница между процессом и потоком
В этой статье давайте рассмотрим очень популярный вопрос интервью: в чем разница между Thread и Process и в чем причина этого.
Фото Тима Моссхолдера на Unsplash
Что такое программы, процессы и потоки?
Чтобы лучше понять, сначала давайте посмотрим, что это такое.
Программа
Программа — это последовательность инструкций, которые компьютер может выполнять или интерпретировать. Компьютерная программа в удобочитаемой форме называется исходным кодом. Обычно исходный код необходимо преобразовать в машинные инструкции с помощью компилятора языка. Полученный файл называется исполняемым.
В качестве альтернативы исходный код может выполняться в интерпретаторе языка. Java компилируется в промежуточную форму, которая затем выполняется интерпретатором Java.

Исполняемый файл Google Chrome (.exe) в Windows.
Процесс
В то время как программа представляет собой пассивный набор инструкций, обычно хранящихся в файле на диске , процесс представляет собой выполнение этих инструкций после их загрузки с диска в память . Процесс — это экземпляр компьютерной программы, программа в процессе выполнения. Каждый процесс запускается с одним потоком, часто называемым основным потоком, но может создавать дополнительные потоки из любого из своих потоков.
С одной и той же программой может быть связано несколько процессов, процесс может создавать другой процесс (дочерний процесс).
Процесс(ы) Google Chrome.
Нить
Поток — это наименьшая единица выполнения внутри процесса. В процессе может быть несколько потоков.

Программа против процесса против потока (изображение Hooman Mallahzadeh)
Итак, давайте сделаем краткий обзор.
Программа — это исполняемый файл, содержащий набор инструкций и пассивно хранящийся на диске.
Процесс — это выполнение этих инструкций после загрузки с диска в память. Это экземпляр компьютерной программы, программа в процессе выполнения. В одной программе может быть несколько процессов. Например, браузер Google Chrome создает совершенно отдельный процесс для каждой отдельной вкладки или дополнительного расширения, которое вы используете.
Поток — это наименьшая единица выполнения внутри процесса. Один процесс может иметь несколько потоков.
Разница между потоком и процессом
Определение
Мы уже рассмотрели это в разделе «Что» выше.
Время создания/прекращения
Процессы требуют больше времени для создания/завершения, чем потоки.
Создание процесса требовало выделения блока управления процессом (PCB). PCB — это структура данных, используемая операционными системами для хранения всей информации о процессе. Он включает в себя карту памяти, список открытых файлов,… Выделение и управление памятью означает, что ОС будет отображать виртуальную память в памяти процесса на физический адрес, что является наиболее трудоемкой частью. Следовательно, создание или уничтожение процесса является относительно дорогостоящим, так как ресурсы должны быть приобретены или высвобождены.

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

Один поток в процессе.
Дополнительный вопрос:
есть ли случай, когда время создания процесса совпадает со временем создания потока?
В Unix есть fork системный вызов, клонирующий дочерний процесс из запущенного процесса. Существует оптимизированный способ клонирования, чтобы он не дублировал родительскую память в дочернюю память, которая копируется при записи. При fork выполнении страницы, общие для родительского и дочернего элементов, помечаются как доступные только для чтения.
Если запись выполняется на странице, доступной только для чтения, она затем копируется, поскольку память между двумя процессами больше не идентична. Поэтому, если выполняются только операции чтения, страницы вообще не будут скопированы.
С fork копированием и записью при создании дочернего процесса меньше накладных расходов, и время его создания будет почти таким же, как время создания потока. Обратите внимание, что это в Unix, и когда мы создаем дочерний процесс, если мы создаем новый процесс, в Unix у нас все еще есть исходные накладные расходы.
Дополнительный вопрос № 2:
правда ли, что создание процесса в Windows обходится дороже, чем в Linux?
Коммуникация и обмен данными
Следующее различие между потоком и процессом заключается в обмене данными и обмене данными.
Процесс является изолированным исполняемым объектом и не использует совместно данные и информацию. Процессы используют для связи механизм IPC (Inter-Process Communication), что значительно увеличивает количество системных вызовов.
Потоки, принадлежащие одному и тому же процессу, могут взаимодействовать через данные, код и файлы, которые они уже совместно используют (см. изображение выше), с очень небольшим количеством системных вызовов или вообще без них. Связь между потоками быстрее для потоков.
Однако из-за того, что потоки используют одно и то же адресное пространство, недопустимая операция, выполняемая потоком, может привести к сбою всего процесса. Таким образом, один некорректно работающий поток может нарушить работу всех остальных потоков. Итак, теперь мы можем понять, почему браузер Google Chrome использует отдельный процесс для каждой вкладки вместо потока. Если мы используем поток для каждой вкладки, весь браузер и все вкладки могут рухнуть, когда один плохой сайт обманом заставит браузер выделить неограниченное количество памяти или что-то похуже.
Переключение контекста
Процессу требуется больше времени для переключения контекста, тогда как потоку требуется меньше времени.
Когда процессы выгружаются из памяти и позже восстанавливаются, их состояние также необходимо сохранять и восстанавливать (см. изображение ниже).
Переключение контекста между потоками в одном и том же процессе чрезвычайно эффективно, поскольку вообще не требует взаимодействия с ОС.

Диаграмма, показывающая переключение процессора с процесса на процесс.
Давайте вспомним разницу между потоком и процессом:
- Процесс означает, что программа выполняется, а поток — наименьшая единица выполнения внутри процесса.
- Процессы обычно независимы, а потоки существуют как подмножества процесса.
- Для создания и завершения процессов требуется больше времени, чем для потоков.
- В отличие от процессов, которым для выполнения межпроцессного взаимодействия (IPC) требуется механизм передачи сообщений или разделяемой памяти, потоки могут взаимодействовать через данные, код и файлы, которые они уже совместно используют.
- Каждый процесс имеет собственное пространство памяти. Потоки, принадлежащие одному и тому же процессу, совместно используют одну и ту же память.
- Переключение контекста между потоками в одном и том же процессе обычно происходит быстрее, чем переключение контекста между процессами.
Поддержка языка программирования Go Goroutine. В чем разница между горутиной и потоком?
Поток имеет большой размер стека (> 1 МБ), если мы планируем иметь тысячи потоков, накладные расходы на размер стека будут потреблять много памяти.
Горутины называются облегченными потоками, управляемыми Go Runtime Scheduler, они существуют в виртуальном пространстве среды выполнения Go, а не в операционной системе. Чтобы сделать стек меньше, среда выполнения Go использует ограниченные стеки изменяемого размера, которые изначально занимают всего 2 КБ на горутин. Несколько горутин могут выполняться в одном потоке.
Стоимость создания Goroutine ничтожно мала по сравнению с потоком. Обычно в приложении Go одновременно работают тысячи горутин.
Дополнительный вопрос для вас:
некоторые языки программирования поддерживают сопрограмму. В чем разница между сопрограммой, горутиной и потоком?
Вывод
В этой статье мы вместе рассмотрели очень фундаментальный термин в вычислительной технике, который называется «Процесс» и «Поток». Мы узнали, что это такое, в чем и почему существуют различия между Process и Thread. Затем мы пойдем дальше и поговорим о Goroutine языка программирования Go.
В следующей статье мы рассмотрим, в чем разница между параллелизмом и параллелизмом, что такое многопоточность и ее плюсы и минусы, так что следите за обновлениями! 😀
использованная литература
- Тема (вычисления) (en.wikipedia.org)
- Темы (cs.uic.edu)
- Процесс против потока: в чем разница? (guru99.com)
- Процесс против потока (blog.bytebytego.com)
Чем процесс отличается от потока
Процессы и потоки in-depth. Обзор различных потоковых моделей
Здравствуйте дорогие читатели. В данной статье мы рассмотрим различные потоковые модели, которые реализованы в современных ОС (preemptive, cooperative threads). Также кратко рассмотрим как потоки и средства синхронизации реализованы в Win32 API и Posix Threads. Хотя на Хабре больше популярны скриптовые языки, однако основы — должны знать все
Потоки, процессы, контексты.
Системный вызов (syscall). Данное понятие, вы будете встречать достаточно часто в данной статье, однако несмотря на всю мощь звучания, его определение достаточно простое Системный вызов — это процесс вызова функции ядра, из приложение пользователя. Режим ядра — код, который выполняется в нулевом кольце защиты процессора (ring0) с максимальными привилегиями. Режим пользователя — код, исполняемый в третьем кольце защиты процессора (ring3), обладает пониженными привилегиями. Если код в ring3 будет использовать одну из запрещенных инструкций (к примеру rdmsr/wrmsr, in/out, попытку чтения регистра cr3, cr4 и т.д.), сработает аппаратное исключение и пользовательский процесс, чей код исполнял процессор в большинстве случаях будет прерван. Системный вызов осуществляет переход из режима ядра в режим пользователя с помощью вызова инструкции syscall/sysenter, int2eh в Win2k, int80h в Linux и т.д.
И так, что же такое поток? Поток (thread) — это, сущность операционной системы, процесс выполнения на процессоре набора инструкций, точнее говоря программного кода. Общее назначение потоков — параллельное выполнение на процессоре двух или более различных задач. Как можно догадаться, потоки были первым шагом на пути к многозадачным ОС. Планировщик ОС, руководствуясь приоритетом потока, распределяет кванты времени между разными потоками и ставит потоки на выполнение.
На ряду с потоком, существует также такая сущность, как процесс. Процесс (process) — не что более иное, как некая абстракция, которая инкапсулирует в себе все ресурсы процесса (открытые файлы, файлы отображенные в память. ) и их дескрипторы, потоки и т.д. Каждый процесс имеет как минимум один поток. Также каждый процесс имеет свое собственное виртуальное адресное пространство и контекст выполнения, а потоки одного процесса разделяют адресное пространство процесса.
- Регистры процессора.
- Указатель на стек потока/процесса.
- Если ваша задача требует интенсивного распараллеливания, используйте потоки одного процесса, вместо нескольких процессов. Все потому, что переключение контекста процесса происходит гораздо медленнее, чем контекста потока.
- При использовании потока, старайтесь не злоупотреблять средствами синхронизации, которые требуют системных вызовов ядра (например мьютексы). Переключение в редим ядра — дорогостоящая операция!
- Если вы пишете код, исполняемый в ring0 (к примеру драйвер), старайтесь обойтись без использования дополнительных потоков, так как смена контекста потока — дорогостоящая операция.
Классификация потоков
- По отображению в ядро: 1:1, N:M, N:1
- По многозадачной модели: вытесняющая многозадачность (preemptive multitasking), кооперативная многозадачность (cooperative multitasking).
- По уровню реализации: режим ядра, режим польователя, гибридная реализация.
Классификация потоков по отображению в режим ядра
- Центральный планировщик ОС режима ядра, который распределяет время между любым потоком в системе.
- Планировщик библиотеки потоков. У библиотеки потоков режима пользователя может быть свой планировщик, который распределяет время между потоками различных процессов режима пользователя.
- Планировщик потоков процесса. Уже рассмотренные нами волокна, ставятся на выполнение именно таким способом. К примеру свой Thread Manager есть у каждого процесса Mac OS X, написанного с использованием библиотеки Carbon.
Модель N:M отображает некоторое число потоков пользовательских процессов N на M потоков режима ядра. Проще говоря имеем некую гибридную систему, когда часть потоков ставится на выполнение в планировщике ОС, а большая их часть в планировщике потоков процесса или библиотеки потоков. Как пример можно привести GNU Portable Threads. Данная модель достаточно трудно реализуема, но обладает большей производительностью, так как можно избежать значительного количества системных вызовов.
Модель N:1. Как вы наверное догадались — множество потоков пользовательского процесса отображаются на один поток ядра ОС. Например волокна.
Классификация потоков по многозадачной модели
Во времена DOS, когда однозадачные ОС перестали удовлетворять потребителя, программисты и архитекторы задумали реализовать многозадачную ОС. Самое простое решение было следующим: взять общее количество потоков, определить какой-нибудь минимальный интервал выполнения одного потока, да взять и разделить между всеми -братьями- потоками время выполнения поровну. Так и появилось понятие кооперативной многозадачности (cooperative multitasking), т.е. все потоки выполняются поочередно, с равным временем выполнения. Никакой другой поток, не может вытеснить текущий выполняющийся поток. Такой очень простой и очевидный подход нашел свое применение во всех версиях Mac OS вплоть до Mac OS X, также в Windows до Windows 95, и Windows NT. До сих пор кооперативная многозадачность используется в Win32 для запуска 16 битных приложений. Также для обеспечения совместимости, cooperative multitasking используется менеджером потоков в Carbon приложениях для Mac OS X.
Однако, кооперативная многозадачность со временем показала свою несостоятельность. Росли объемы данных хранимых на винчестерах, росла также скорость передачи данных в сетях. Стало понятно, что некоторые потоки должны иметь больший приоритет, как-то потоки обслуживания прерываний устройств, обработки синхронных IO операций и т.д. В это время каждый поток и процесс в системе обзавелся таким свойством, как приоритет. Подробнее о приоритетах потоков и процессов в Win32 API вы можете прочесть в книге Джефри Рихтера, мы на этом останавливатся не будем Таким образом поток с большим приоритетом, может вытеснить поток с меньшим. Такой прицип лег в основу вытесняющей многозадачности (preemptive multitasking). Сейчас все современные ОС используют данный подход, за исключением реализации волокон в пользовательском режиме.
Классификация потоков по уровню реализации
- Реализация потоков на уровне ядра. Проще говоря, это классическая 1:1 модель. Под эту категорию подпадают:
- Потоки Win32.
- Реализация Posix Threads в Linux — Native Posix Threads Library (NPTL). Дело в том, что до версии ядра 2.6 pthreads в Linux был целиком и полностью реализован в режиме пользователя (LinuxThreads). LinuxThreads реализовывалf модель 1:1 следующим образом: при создании нового потока, библиотека осуществляла системный вызов clone, и создавало новый процесс, который тем не менее разделял единое адресное пространство с родительским. Это породило множество проблем, к примеру потоки имели разные идентификаторы процесса, что противоречило некоторым аспектам стандарта Posix, которые касаются планировщика, сигналов, примитивов синхронизации. Также модель вытеснения потоков, работала во многих случаях с ошибками, по этому поддержку pthread решено было положить на плечи ядра. Сразу две разработки велись в данном направлении компаниями IBM и Red Hat. Однако, реализация IBM не снискала должной популярности, и не была включена ни в один из дистрибутивов, потому IBM приостановила дальнейшую разработку и поддержку библиотеки (NGPT). Позднее NPTL вошли в библиотеку glibc.
- Легковесные ядерны потоки (Leight Weight Kernel Threads — LWKT), например в DragonFlyBSD. Отличие этих потоков, от других потоков режима ядра в том, что легковесные ядерные потоки могут вытеснять другие ядерные потоки. В DragonFlyBSD существует множество ядерных потоков, например поток обслуживания аппаратных прерываний, поток обслуживания программных прерываний и т.д. Все они работают с фиксированным приоритетом, так вот LWKT могут вытеснять эти потоки (preempt). Конечно это уже более специфические вещи, про которые можно говорить бесконечно, но приведу еще два примера. В Windows все потоки ядра выполняются либо в контексте потока инициировавшего системный вызов/IO операцию, либо в контексте потока системного процесса system. В Mac OS X существует еще более интересная система. В ядре есть лишь понятие task, т.е. задачи. Все операции ядра выполняются в контексте kernel_task. Обработка аппаратного прерывания, к примеру, происходит в контексте потока драйвера, который обслуживает данное прерывание.
- Реализация потоков в пользовательском режиме. Так как, системный вызов и смена контекста — достаточно тяжелые операции, идея реализовать поддержку потоков в режиме пользователя витает в воздухе давно. Множество попыток было сделано, однако данная методика популярности не обрела:
- GNU Portable Threads — реализация Posix Threads в пользовательском режиме. Основное преимущество — высокая портабельность данной библиотеки, проще говоря она может быть легко перенесена на другие ОС. Проблему вытиснения потоков в данной библиотеке решили очень просто — потоки в ней не вытесняются Ну и конечно ни о какой мультмпроцессорности речь идти не может. Данная библиотека реализует модель N:1.
- Carbon Threads, которые я упоминал уже не раз, и RealBasic Threads.
- Гибридная реализация. Попытка использовать все преимущества первого и второго подхода, но как правило подобные мутанты обладают гораздо бОльшими недостатками, нежели достоинствами. Один из примеров: реализация Posix Threads в NetBSD по модели N:M, которая была посже заменена на систему 1:1. Более подробно вы можете прочесть в публикации Scheduler Activations: Effective Kernel Support for the User-Level Management of Parallelism.
Win32 API Threads
Если вы все еще не устали, предлагаю небольшой обзор API для работы с потоками и средствами синхронизации в win32 API. Если вы уже знакомы с материалом, можете смело пропускать этот раздел
Потоки в Win32 создаются с помощью функции CreateThread, куда передается указатель на функцию (назовем ее функцией потока), которая будет выполнятся в созданом потоке. Поток считается завершенным, когда выполнится функция потока. Если же вы хотите гарантировать, что поток завершен, то можно воспользоватся функцией TerminateThread, однако не злоупотребляйте ею! Данная функция «убивает» поток, и отнюдь не всегда делает это корректно. Функция ExitThread будет вызвана неявно, когда завершится функция потока, или же вы можете вызвать данную функцию самостоятельно. Главная ее задача — освободить стек потока и его хендл, т.е. структуры ядра, которые обслуживают данный поток.
Поток в Win32 может пребывать в состоянии сна (suspend). Можно «усыпить поток» с помощью вызова функции SuspendThread, и «разбудить» его с помощью вызова ResumeThread, также поток можно перевести в состояние сна при создании, установив значение параметра СreateSuspended функции CreateThread. Не стоит удивлятся, если вы не увидите подобной функциональности в кроссплатформенных библиотеках, типа boost::threads и QT. Все очень просто, pthreads просто не поддерживают подобную функциональность.
Средства синхронихации в Win32 есть двух типов: реализованные на уровне пользователя, и на уровне ядра. Первые — это критические секции (critical section), к второму набору относят мьютексы (mutex), события (event) и семафоры (semaphore).
Критические секции — легковесный механизм синхронизации, который работает на уровне пользовательского процесса и не использует тяжелых системных вызовов. Он основан на механизме взаимных блокировок или спин локов (spin lock). Поток, который желает обезопасить определенные данные от race conditions вызывает функцию EnterCliticalSection/TryEnterCriticalSection. Если критическая секция свободна — поток занимает ее, если же нет — поток блокируется (т.е. не выполняется и не отъедает процессорное время) до тех пор, пока секция не будет освобождена другим потоком с помощью вызова функции LeaveCriticalSection. Данные функции — атомарные, т.е. вы можете не переживать за целостность ваших данных
- Они использует примитивы ядра при выполнении, т.е. системные вызовы, что сказывается не производительности.
- Могут быть именованными и не именованными, т.е. каждому такому объекту синхронизации можно присвоить имя.
- Работают на уровне системы, а не на уровне процесса, т.е. могут служить механизмом межпроцессного взаимодействия (IPC).
- Используют для ожидания и захвата примитива единую функцию: WaitForSingleObject/WaitForMultipleObjects.
Posix Threads или pthreads
Сложно представить, какая из *nix подобных операционных систем, не реализует этот стандарт. Стоит отметить, что pthreads также используется в различных операционных системах реального времени (RTOS), потому требование к этой библиотеке (вернее стандарту) — жестче. К примеру, поток pthread не может пребывать в состоянии сна. Также в pthread нет событий, но есть гораздо более мощный механизм — условных переменных (conditional variables), который с лихвой покрывает все необходимые нужды.
Поговорим об отличиях. К примеру, поток в pthreads может быть отменен (cancel), т.е. просто снят с выполнения посредством системного вызова pthread_cancel в момент ожидания освобождения какого-нибудь мьютекса или условной переменной, в момент выполнения вызова pthread_join (вызывающий поток блокируется до тех пор, пока не закончит свое выполнение поток, приминительно к которому была вызвана функция) и т.д. Для работы с мьютексами и семафорами существует отдельные вызовы, как-то pthread_mutex_lock/pthread_mutex_unlock и т.д.
Conditional variables (cv) обычно используется в паре с мьютексами в более сложных случаях. Если мьютекс просто блокирует поток, до тех пор, пока другой поток не освободит его, то cv создают условия, когда поток может заблокировать сам себя до тех пор, пока не произойдет какое-либо условия разблокировки. Например, механизм cv помогает эмулировать события в среде pthreads. Итак, системный вызов pthread_cond_wait ждет, пока поток не будет уведомлен о том, что случилось определенное событие. pthread_cond_signal уведомляет один поток из очереди, что cv сработала. pthread_cond_broadcast уведомляет все потоки, которые вызывали pthread_cond_wait, что сработала cv.
Прощальное слово
На сегодня пожалуй все, иначе информации станет слишком много. Для интересующихся, есть несколько полезных ссылок и книг внизу Также высказывайте свое мнение, интересны ли вам статьи по данной теме.
UPD: дополнил статью небольшой информацией о режиме ядра и режиме пользователя.
UPD2: исправил досадные промахи и ошибки. Спасибо комментаторам
Чем отличается процесс от потока?

Процесс — экземпляр программы во время выполнения, независимый объект, которому выделены системные ресурсы (например, процессорное время и память). Каждый процесс выполняется в отдельном адресном пространстве: один процесс не может получить доступ к переменным и структурам данных другого. Если процесс хочет получить доступ к чужим ресурсам, необходимо использовать межпроцессное взаимодействие. Это могут быть конвейеры, файлы, каналы связи между компьютерами и многое другое.
Для каждого процесса ОС создает так называемое «виртуальное адресное пространство», к которому процесс имеет прямой доступ. Это пространство принадлежит процессу, содержит только его данные и находится в полном его распоряжении. Операционная система же отвечает за то, как виртуальное пространство процесса проецируется на физическую память.
Поток(thread) — определенный способ выполнения процесса, определяющий последовательность исполнения кода в процессе. Потоки всегда создаются в контексте какого-либо процесса, и вся их жизнь проходит только в его границах. Потоки могут исполнять один и тот же код и манипулировать одними и теми же данными, а также совместно использовать описатели объектов ядра, поскольку таблица описателей создается не в отдельных потоках, а в процессах. Так как потоки расходуют существенно меньше ресурсов, чем процессы, в процессе выполнения работы выгоднее создавать дополнительные потоки и избегать создания новых процессов.
Чем процесс отличается от потока
Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal
