Если ядро порождается как потоки и находится в памяти, то как команда ps их идентифицировать, если это не нормальный процесс, и я дам вам больше взглянуть здесь:

root         2     0  0 févr.04 ?     00:00:00 [kthreadd]
root         3     2  0 févr.04 ?     00:00:01 [ksoftirqd/0]
root         5     2  0 févr.04 ?     00:00:00 [kworker/0:0H]

эти потоки ядра, как мы видим, имеют ту же информацию, что и идентификатор дочернего процесса linux, родительский идентификатор (0) и владелец пользователя (root)

Пожалуйста, объясните это.

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

Другой вопрос: когда компилятор создает исполняемый файл, он создает vma (адрес виртуальной памяти), который затем используется процессором для выделения пространства памяти; как компилятор может генерировать эти адреса?

Спасибо вам, ребята.

1 ответ1

0

Я не могу однозначно ответить на вопрос "темы ядра" для Linux. Что касается Windows, я могу вам сказать, что "потоки ядра" - это просто потоки, созданные из некоторой другой подпрограммы режима ядра, выполняющие процедуры, которые никогда не переходят в режим пользователя. Когда планировщик выбирает поток для выполнения, он возобновляет свое предыдущее состояние (пользователь или ядро, что бы это ни было); ЦПУ не нужно "различать". Поток выполняется в режиме ядра, потому что это то, что он делал в прошлый раз.

В Windows они, как правило, создаются с помощью так называемого "системного" процесса в качестве родителя, но на самом деле они могут быть созданы в любом процессе. Итак, в Unix они могут иметь родительский идентификатор, равный нулю? то есть принадлежность к процессу? Это на самом деле не имеет значения, если поток не пытается использовать ресурсы уровня процесса.

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

Вторая часть ответа заключается в том, что адреса, такие как они, назначаются компоновщиком, а не компилятором. Что на самом деле просто откладывает вопрос - как это может сделать это? Под чем, я думаю, вы подразумеваете, как он узнает, какие адреса будут доступны во время выполнения? Ответ «практически все».

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .