Подтвердить что ты не робот

Темы: Почему все пользовательские потоки должны отображаться в поток ядра?

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

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

4b9b3361

Ответ 1

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

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

Причина, по которой пользовательские потоки должны быть связаны с потоками ядра, заключается в том, что пользовательский поток - это всего лишь куча данных в пользовательской программе. Нити Kernel - это настоящие потоки в системе, поэтому для пользовательского потока, чтобы добиться прогресса, пользовательская программа должна иметь свой планировщик, используя пользовательский поток, а затем запускать его в потоке ядра. Сопоставление между потоками пользователей и потоками ядра не обязательно должно быть индивидуально (1:1); вы можете иметь несколько потоков пользователей, совместно использующих один и тот же поток ядра (только один из этих пользовательских потоков выполняется одновременно), и вы можете иметь один пользовательский поток, который вращается в разных потоках ядра в сопоставлении 1: n.

Ответ 2

Я думаю, что пример реального мира устранит путаницу, поэтому давайте посмотрим, как это делается в Linux.

Прежде всего, Linux не различает процесс и поток, объект, который может быть запланирован, называется задачей в Linux и представлен task_struct. Поэтому всякий раз, когда вы выполняете системный вызов fork(), создается новая task_struct, которая содержит данные (или указатель), связанные с новой задачей.

Итак, в мире Linux поток ядра означает объект task_struct (структура). Поскольку планировщик знает об этих объектах, которые могут быть назначены различным ЦП (логическим или физическим). Другими словами, если вы хотите, чтобы планировщик Linux планировал ваш процесс, вы должны создать task_struct.

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

Теперь давайте ответим на ваш вопрос

why a user thread must always be mapped to a specific kernel thread.

Допустим, вы создали некоторые потоки, используя ваш EE. в конечном итоге они должны выполняться процессором, и из приведенного выше объяснения мы знаем, что вы (поток) должны иметь task_struct, чтобы назначить некоторый процессор. Вот почему отображение должно существовать. Своей обязанностью вашей EE создать task_structs.

Если ваш EE использует много моделей, то он создаст только один task_struct для всех потоков, и он будет планировать все эти потоки на этом task_struct. Подумайте об этом, так как есть один CPU (task_struct) и многие процессы (потоки, созданные в EE), ваша операционная система (EE) будет мультиплексировать эти процессы на одном CPU.

Если он использует одну или одну модель, то для каждого потока, созданного в EE, будет один task_struct. Поэтому, когда вы создаете новый поток в своем EE, в ядре создается соответствующий task_struct.

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