Как работает многопоточность?

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

  1. на уровень потоков, где у каждого потока(ну то есть задачи/программы) есть доступ к общим ресурсам, и
  2. на уровне процессов, где у каждого потока(иначе говоря, задачи или программы) такого доступа нет.

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


Ответы (1 шт):

Автор решения: Serge3leo

Что есть что в схеме ядро->процесс->поток ?

В достаточно популярном стандарте POSIX (более менее соответствует многим ОС):

  • Процесс - полноправный объект ОС, имеет права (ID пользователя, группы и прочая), открытые каналы и сокеты, текущий каталог, локаль и прочие права и обязанности. К нему можно подключиться отладчиком и т.п. Одно из немаловажных свойств процесса - хорошая изоляция от окружения, в частности, он может аварийно завершиться почти ничего не повредив, или его можно "убить";
  • Поток - подобъект объекта "процесс" (в современных реализациях виден ОС, но это необязательно), описан как "поток управления", т.е., как минимум, имеет собственный стек, собственную текущую инструкцию (функцию), собственные состояния целочисленного и плавающего вычислителя. И имеет доступ и управляет всеми ресурсам процесса в состав которого входит. В процессе есть, как минимум, один поток (главный). Аварийное завершение любого потока, почти всегда - авария для всего процесса. Так же как и принудительно прервать поток, хоть иногда и хочется, но, обычно, весьма затруднительно (скажем, стандарты языков C11/C++11/Python вообще не предоставляют таковых возможностей, только уговорить);
  • Ядро (ЦП) - не важно с HT/SMT или без, это ресурс, который выделяется процессу (или, сейчас, чаще потоку, как его части, но иногда, редко, ОС не разбирается в потоках) на временной или постоянной основе. Если ОС разбирается в потоках, то часто разным потокам можно назначать разные подмножества процессоров и прочая, прочая.

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

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

В реальных ОС, например, в Linux поток от процесса отличается только настройками при создании, т.е. "неглавный" поток процесса, это фактически такой же процесс, но настроенный на полное разделение всего, что только можно, с главным потоком (да и чего нельзя, тоже, например, seteuid(), смена пользователя многопоточного процесса в Linux это отдельная песня). А в Windows права доступа потоков могут вообще отличаться. Но вот в BSD или macOS/iOS, потоки это совсем совсем не процессы, это другое.

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

Разница, конечно, есть в деталях, там же, где и дьявол.

К примеру, на старых Python c GIL (т.е. потоки могут на разных ядрах исполнятся, но GIL заставляет их работать стык-в-стык, по струнке), при желании, порождаете несколько процессов, выделяете общую память и работаете. Только вот с объектами в общей памяти - трудности, но с простыми данными проблем нет.

Итого, основные различия больше административные: процесс для человека (пользователя, администратора и т.п.), поток для процесса, ядро для потока. (пользователь->процесс->поток->ядро)

→ Ссылка