ЗНАЕТЕ ЛИ ВЫ?

Реализация процессов и потоков



 

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

Создание потока также состоит из нескольких этапов. Сначала работающий процесс обращается к функции CreateThread, которая вызывает процедуру внутри kernel32.dll. Эта процедура вы­деляет в вызывающем процессе память для стека режима пользователя, а затем обращается к системному вызову NtCreateThread, чтобы создать объект потока для исполняющей системы, проинициализировать его, а также создать и проинициализировать блок управления потоком. Затем поток начинает работу с собственной инициализации.

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

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

Текущий поток выполняет программу планировщика при одном из следующих условий:

1) поток блокируется на семафоре, мьютексе, событии, операции ввода-выво­да и т. д;

2) поток сигнализирует каким-либо объектом (например, выполняет операцию up на семафоре);

3) истекает квант времени работающего потока.

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

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

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

Планировщик также вызывается при еще двух условиях:

1) завершается операция ввода-вывода;

2) истекает ожидание таймера.

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

Теперь рассмотрим сам алгоритм планирования. Интерфейс Win32 API содержит два вызова, предоставляющих процессам возможность влиять на пла­нирование потоками. Алгоритм планирования в значительной степени определяется этими вызовами.

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

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

Планировщик работает следующим образом. В системе существует 32 уровня приоритета, пронумерованные от 0 до 31. 42 комбинации отображаются на эти 32 приоритета, определяя базовый приоритет потока. Кроме того, у каждого потока есть текущий приоритет, кото­рый может быть выше (но не ниже) базового приоритета.

Чтобы использовать эти приоритеты для планирования, система содержит мас­сив из 32 элементов, соответствующих приоритетам от 0 до 31. Каждый элемент массива указывает на начало списка готовых пото­ков с соответствующим приоритетом. Базовый алгоритм планирования состоит из процедуры сканирования массива от приоритета 31 до приоритета 0. Как только найден непустой элемент, выбирается поток в начале очереди и запускается на один квант времени. Когда квант истекает, поток направляется в конец очереди своего приоритета, а следующим выбирается поток в начале очереди. Другими сло­вами, когда есть несколько готовых потоков с наивысшим уровнем приоритета, они запускаются поочередно, получая каждый по одному кванту времени. Если гото­вых потоков нет, запускается бездействующий поток.

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

В системе Windows 2000 Professional длительность кванта по умолчанию равна 20 мс; на однопроцессорных серверах его значение равно 120 мс; на многопроцессорных системах используют­ся различные другие варианты в зависимости от частоты процессора. Более ко­роткий квант улучшает работу интерактивных процессов, тогда как более длин­ный квант снижает количество переключений контекста и тем самым увеличивает производительность. Значения по умолчанию при желании могут быть увеличены в 2, 4 или 6 раз.

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

Загрузка Windows 2000

 

Прежде чем операционная система Windows 2000 сможет начать работу, она долж­на загрузиться. Процесс загрузки создает начальные процессы. С точки зрения аппаратного обеспечения, процесс загрузки состоит из чтения первого сек­тора первого диска (главной загрузочной записи), после чего управление передается прочитанной програм­ме. Эта короткая программа на ассемблере считывает таблицу разделов, что­бы определить, в каком разделе содержится загружаемая операционная система. Найдя раздел с операционной системой, начальный загрузчик считывает первый сектор этого раздела, называемый загрузочным сектором, и передает управление ему. Программа, содержащаяся в загрузочном секторе, считывает корневой ката­лог своего дискового раздела, находит в нем файл ntldr. Если этот файл удается найти, он загружается в память и ему передается управление. Программа ntldr загружает операционную систему Windows 2000. Существует не­сколько версий загрузочного сектора в зависимости от формата раздела (FAT-16, FAT-32 или NTFS). При установке Windows 2000 на диск записываются соответ­ствующие версии главной загрузочной записи и загрузочного сектора.

Затем программа ntldr считывает файл Boot.ini, представляющий собой един­ственный файл с информацией о конфигурации, не содержащейся в реестре. Он хранит в себе списки всех версий файлов hal.dll и ntoskernl.exe, которые могут быть загружены с данного раздела диска. В этом файле также содержатся такие пара­метры, как количество центральных процессоров и оперативной памяти, сколько памяти отводить процессу пользователя (2 или 3 Гбайт), а также на какой часто­те работают часы реального времени. Затем программа ntldr выбирает и загру­жает файлы hal.dll и ntoskernl.exe, а также файл bootvid.dll, представляющий собой видеодрайвер по умолчанию. Он обеспечивает вывод на дисплей во время процес­са загрузки. После этого программа ntldr считывает реестр, чтобы найти драйверы, необходимые для завершения загрузки (например, драйверы клавиатуры и мыши, а также десятки других драйверов, требуемых для управления различными микро­схемами на материнской плате). Наконец, загрузчик считывает все эти драйверы и передает управление программе ntoskernl.exe.

После запуска операционная система выполняет некоторые общие процедуры инициализации, а затем вызывает компоненты исполняющей системы, чтобы те также выполнили собственную инициализацию. Например, менеджер объектов подготавливает свое пространство имен, чтобы другие компоненты могли обра­щаться к нему и добавлять свои объекты в пространство имен. Многие компонен­ты также выполняют определенные действия, относящиеся к их функциям. В частности, менеджер памяти настраивает начальные таблицы страниц, а менеджер plug-and-play определяет, какие устройства ввода-вывода присутствуют, и загружает их драйверы. Вся загрузка состоит из десятков этапов, в течение которых на экране отображается полоса прогресса, растущая по мере выполнения очередных этапов. Последний этап заключается в создании первого настоящего пользовательского процесса – сеансового менеджера smss.exe. Как только этот процесс начинает рабо­ту, загрузка считается законченной.

Сеансовый менеджер представляет собой «родной» процесс операционной системы Windows 2000. Он обращается к истинным системным вызовам и не пользуется вызовами подсистемы окружения Win32, которая в тот момент еще даже не работает. Одной из его первоочередных обязанностей является запуск этой подсистемы (csrss.exe). Он также считывает с диска ульи реестра и узнает из них, что еще он должен сделать. Как правило, его работа заключается в помещении мно­жества объектов в пространство имен менеджера объектов, создании дополнитель­ных файлов подкачки и открытии нужных DLL. Завершив свою работу, сеансо­вый менеджер создает демон регистрации winlogon.exe.

В этот момент операционная система загружена и работает. Теперь пора запус­тить служебные процессы (демоны в пространстве пользователя) и позволить пользователям регистрироваться в системе. Сначала winlogon.exe создает менед­жера аутентификации (lsass.exe), а затем запускает родительский процесс всех слу­жебных процессов (sennces.exe). Последний процесс по информации, хранящейся в реестре, определяет, какие демоны в пространстве пользователя нужно запустить и в каких файлах они находятся. После этого он приступает к их созданию. Как правило, уже после того, как первый пользова­тель зарегистрировался в системе, но еще до того, как он успел в ней что-либо сделать, в операционной системе Windows 2000 наблюдается высокая активность с большим количеством обращений к диску. Это программа services.exe создает системные службы. Кроме того, она загружает все оставшиеся (еще не загружен­ные) драйверы устройств.

Программа winlogon.exe также отвечает за регистрацию всех пользователей в системе. После успешного входа пользователя в систему про­грамма winlogon.exe получает из реестра профиль пользователя и определяет по нему, какую оболочку запустить. Стан­дартный рабочий стол Windows представляет собой программу explorer.exe, у которой настроены некоторые параметры. При желании пользо­ватель может выбрать в качестве оболочки другую программу, для чего ему нужно просто отредактировать реестр. Отметим, что редактирование реестра требует особой внимательности и осторожности, а всего одна допущенная ошибка может сделать систему незагружаемой.

 

8.3. Управление памятью вWindows 2000

 

Основные понятия

В операционной системе Windows 2000 у каждого пользовательского процесса есть собственное виртуальное адресное пространство. Виртуальные адреса 32-разряд­ные, поэтому у каждого процесса 4 Гбайт виртуального адресного пространства. Нижние 2 Гбайт за вычетом около 256 Мбайт доступны для программы и данных процесса; верхние 2 Гбайт защищенным образом отображаются на память ядра. Страницы виртуального адресного пространства имеют фиксированный размер (4 Кбайт на компьютере с процессором Pentium) и подгружаются по требованию. Нижние и верхние 64 Кбайт каждого виртуального адресного пространства в обычном состоянии не отображаются на физическую память. Это делается преднамеренно, что­бы облегчить перехват программных ошибок. Недействительные указатели часто имеют значение 0 или -1, и попытки их использования в системе Windows 2000 вызовут немедленное прерывание вместо чтения или, что еще хуже, записи слова по неверному адресу. Однако когда запускаются старые программы MS-DOS в ре­жиме эмуляции, нижние 64 Кбайт могут отображаться на физическую память.

Начиная с адреса 64 К, могут располагаться приватные данные и программа пользователя. Они могут занимать почти 2 Гбайт. Последний фрагмент этих 2 Гбайт памяти содержит некоторые системные указатели и таймеры, используемые со­вместно всеми пользователями в режиме доступа «только чтение». Отображение этих данных в эту область памяти позволяет всем процессам получать к ним дос­туп без лишних системных вызовов.

Верхние 2 Гбайт виртуального адресного пространства содержат операционную систему, включая код, данные и выгружаемый и невыгружаемый пулы (использу­емые для объектов и т. д.). Верхние 2 Гбайт используются совместно всеми про­цессами, кроме таблиц страниц, которые являются индивидуальными для каждо­го процесса. Верхние 2 Гбайт процессам в режиме пользователя запрещены для записи, а по большей части также запрещены и для чтения. Причина, по которой они размещаются здесь, заключается в том, что когда поток обращается к систем­ному вызову, он переключается в режим ядра, но остается все тем же потоком. Если сделать всю операционную систему и все ее структуры данных (как и весь пользо­вательский процесс) видимыми в адресном пространстве потока, когда он переклю­чается в режим ядра, то отпадает необходимость в изменении карты памяти или выгрузке кэша при входе в ядро. Все, что нужно сделать, – это переключиться на стек режима ядра. Платой за более быстрые системные вызовы при данном подходе является уменьшение приватного адресного пространства для каждого процес­са. Большим базам данных уже сейчас становится тесно в таких рамках, вот поче­му в версиях Windows 2000 Advanced server и Datacenter Server есть возможность использования 3 Гбайт для адресного пространства пользовательских процессов.

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

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

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

Подобный выбор (усложнение системы или увеличение производительности и дополнительные функции), как правило, разрешается в пользу последнего, так как достоинства лучшей производительности и большего числа функций очевид­ны, тогда как недостатки усложнения системы (сложность поддержки и увеличе­ние частоты сбоев) бывает сложно учесть.

У свободных и зарезервированных страниц никогда не бывает теневых страниц на диске и обращение к ним всегда приво­дит к страничным прерываниям. Теневые страницы на диске организованы в один или несколько файлов под­качки. Может быть организовано до 16 файлов подкачки, для повышения произ­водительности операций ввода-вывода они могут быть распределены по отдель­ным дискам, которых также может быть до 16. У каждого файла есть начальный размер и максимальный размер, до которого он может вырасти при необходимос­ти. Эти файлы могут сразу быть созданы максимального размера во время уста­новки системы, чтобы уменьшить вероятность их сильной фрагментации, но с по­мощью панели управления позднее можно создать новые файлы. Операционная система следит за тем, какие виртуальные страницы на какую часть файла подкач­ки отображаются. Страницы, содержащие исполняемый текст программ, не дуб­лируются в файлах подкачки. В файлах подкачки хранятся только изменяемые страницы.

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

В Windows 2000 два и более процессов могут одновременно отображать на свои виртуальные адресные пространства, возможно, в различные адреса, одну и ту же часть одного и того же файла. Читая и записывая сло­ва памяти, процессы могут общаться друг с другом и передавать друг другу ин­формацию с очень большой скоростью, так как копирование при этом не требует­ся. У различных процессов могут быть различные права доступа. Поскольку все процессы, использующие отображаемый на память файл, совместно используют одни и те же страницы, изменения, произведенные одним процессом, немедленно становятся видимыми для всех остальных процессов, даже если файл на диске еще не был обновлен. Также предпринимаются меры, благодаря которым процесс, от­крывающий файл для нормального чтения, видит текущие страницы в ОЗУ, а не устаревшие страницы с диска.

Следует отметить, что при совместном использовании двумя программами од­ного файла DLL может возникнуть проблема, если одна из программ изменит ста­тические данные файла. Если не предпринять специальных действий, то другой процесс увидит измененные данные, что, скорее всего, не соответствует намерени­ям этого процесса. Эта проблема решается таким способом: все отображаемые стра­ницы помечаются как доступные только для чтения, хотя в то же время некоторые из них тайно помечаются как в действительности доступные и для записи. Когда к такой странице происходит обращение операции записи, создается приват­ная копия этой страницы и отображается на память. Теперь в эту страницу мож­но писать, не опасаясь задеть других пользователей или оригинальную копию на диске. Такая техника называется копированием при записи.

 

 





Последнее изменение этой страницы: 2016-08-16; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.238.107.166 (0.008 с.)