Реализация понятия последовательного процесса в операционных системах

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

- идентификатор процесса (Process Identifier, PID);

- тип (или класс) процесса, который определяет для супервизора некоторые пра­вила предоставления ресурсов;

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

- переменную состояния, которая определяет, в каком состоянии находится про­цесс (готов к работе, выполняется, ожидает устройства ввода-вывода и т. д.);

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

- информацию о ресурсах, которыми процесс владеет и/или имеет право пользо­ваться (указатели на открытые файлы, информация о незавершенных опера­циях ввода-вывода и др.);

- место (или его адрес) для организации общения с другими процессами;


Понятия вычислительного процесса и ресурса_______________________________ 35

- параметры времени запуска (момент времени, когда процесс должен активизи­роваться, и периодичность этой процедуры);

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

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

В некоторых операционных системах количество описателей определяется жест­ко и заранее (на этапе генерации варианта операционной системы или в конфигу­рационном файле, который используется при загрузке ОС), в других по мере необходимости система может выделять участки памяти под новые описатели. На­пример, в уже мало кому известной системе OS/2, которая несколько лет тому назад многими специалистами считалась одной из лучших ОС для персональных компьютеров, максимально возможное количество описателей задач указывается в конфигурационном файле CONFIG.SYS. Например, строка THREADS=1024 в файле CONFIG.SYS означает, что всего в системе может параллельно существовать и вы­полняться до 1024 задач, включая вычислительные процессы и их потоки.

В ныне широко распространенных системах Windows NT/2000/XP количество описателей нигде в явном виде не задается. Это переменная величина, и она опре­деляется самой операционной системой. Однако посмотреть на текущее количе­ство таких описателей можно. Если, работая в Windows NT/2000/XP, нажать од­новременно комбинацию клавиш Ctrl+Shift+Esc, появится окно Диспетчера задач. На вкладке Быстродействие этой программы мы увидим поле с названием Всего де­скрипторов и соответствующее число. Тут же указывается количество дескрипто­ров для управления потоками (задачами) и число полноценных вычислительных процессов. Более подробно о процессах и потоках см. далее.

В операционных системах реального времени чаще всего количество процессов фиксируется, и, следовательно, целесообразно заранее определять (на этапе гене­рации или конфигурирования ОС) количество дескрипторов. Для использования таких операционных систем в качестве систем общего назначения (что нынче уже нехарактерно)' обычно количество дескрипторов бралось с некоторым запасом,

1 В недалеком прошлом достаточно часто и качестве вычислительных систем общего назначения при­обретались мини-ЭВМ и устанавливали на них ОС реального времени.


36_____________________________________________ Глава 1. Основные понятия

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

Для более эффективной обработки данных в системах реального времени целесо­образно иметь постоянные задачи, полностью или частично всегда существующие в системе независимо от того, поступило на них требование или нет. Каждая по­стоянная задача обладает некоторой собственной областью оперативной памяти (ОЗУ-резидентная задача, или просто резидентная задача) независимо от того, выполняется задача в данный момент или нет. Эта область, в частности, может использоваться для хранения данных, полученных задачей ранее. Данные могут храниться в ней и тогда, когда задача находится в состоянии ожидания или даже в состоянии бездействия.

Для аппаратной поддержки работы операционных систем с этими информацион­ными структурами (дескрипторами задач) в процессорах могут быть реализованы соответствующие механизмы. Так, например, в микропроцессорах Intel 80x86 (см. главу 4) имеется специальный регистр TR (Task Register), указывающий мес­тонахождение специальной информационной структуры — сегмента состояния задачи (Task State Segment, TSS), в котором при переключении с задачи на задачу автоматически сохраняется содержимое регистров процессора [1,8, 48].

Поскольку между терминами «процесс» и «задача» со временем появилось суще­ственное различие, мы сейчас подробно рассмотрим этот вопрос.

Процессы и задачи

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

Мультипрограммный режим предполагает, что операционная система организует параллельное выполнение нескольких вычислительных процессов на одном ком­пьютере. И каждый вычислительный процесс может, в принципе, никак не зави­сеть от другого вычислительного процесса. Разве что они могут задержать выпол­нение друг друга из-за необходимости поочередно разделять ресурсы или сильно задерживать выполнение друг друга при владении неразделяемым ресурсом. У них может не быть ни общих файлов, ни общих переменных. Они вообще могут при­надлежать разным пользователям. Просто эти процессы, с позиций внешнего на­блюдателя, выполняются на одном и том же компьютере в одно и то же время. Хотя могут выполняться и в разное время, и на разных компьютерах. Главное — это то, что мультипрограммный режим обеспечивает для этих процессов их неза­висимость. Каждому процессу операционная система выделяет затребованные ре­сурсы, он выполняется как бы на отдельной виртуальной машине. Средства защиты системы должны обеспечить невмешательство одного вычислительного процесса в другой вычислительный процесс. И если такую защиту обеспечить невозможно,


Понятия вычислительного процесса и ресурса_______________________________ 37

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

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

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

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

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

' Поток выполнения (thread) не следует путать с потоком данных (stream).


38_____________________________________________ Глава 1. Основные понятия

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

Однако желательно иметь еще и возможность задействовать внутренний паралле­лизм, который может быть в самих процессах. Такой внутренний параллелизм встречается достаточно часто и позволяет ускорить вычисления. Например, неко­торые операции, выполняемые приложением, могут требовать для своего испол­нения достаточно длительное использование центрального процессора. В этом случае при интерактивной работе с приложением пользователь вынужден долго ожидать завершения заказанной операции и не может управлять приложением до тех пор, пока операция не выполнится до самого конца. Такие ситуации встреча­ются достаточно часто, например, при работе с графическими редакторами при обработке больших изображений с высокой степенью детализации. Если же про­граммные модули, исполняющие такие длительные операции, оформлять в виде самостоятельных «подпроцессов» (легковесных процессов, потоков выполнения, или задач), которые могут выполняться параллельно с другими подпроцессами (потоками, задачами), то у пользователя появляется возможность параллельно выполнять несколько операций в рамках одного приложения (процесса). Легко­весными эти процессы называют потому, что операционная система не должна для них организовывать полноценную виртуальную машину, то есть эти задачи, преж­де всего, не имеют своих собственных ресурсов, а развиваются в том же виртуаль­ном адресном пространстве, могут пользоваться теми же файлами, виртуальными устройствами и иными ресурсами, выделенными ОС данному процессу. Единствен­ное, что они имеют свое — это процессорный ресурс. В однопроцессорной системе потоки выполнения (задачи) разделяют между собой процессорное время так же, как это делают обычные процессы, а в мультипроцессорной системе они могут выполняться одновременно, если не встречают конкуренции из-за обращения к иным ресурсам.

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


Понятия вычислительного процесса и ресурса_______________________________ 39

Особенно эффективно можно использовать многопоточность для выполнения рас­пределенных приложений. Например, многопоточный сервер может параллельно выполнять запросы сразу нескольких клиентов. Как известно, операционная сис­тема OS/2 была одной из первых систем, используемых в персональных компью­терах, которая поддерживала многопоточность. В середине 90-х годов для этой опе­рационной системы было создано большое количество приложений, в которых наличие механизмов многопоточной обработки реально приводило к существен­ному повышению скорости вычислений. Для систем Windows, с которыми мы все имеем дело, ярко выраженной многопоточностью обладают такие продукты, как SQL Server, Oracle. И хотя те же Word, Excel, Internet Explorer также при своей работе образуют потоки, явного параллелизма в этих программах почти не под­держивается. Поэтому при увеличении числа процессоров в компьютере такие программы не начинают выполняться быстрее.

Итак, сущность «поток выполнения» была введена для того, чтобы именно с помо­щью этих единиц распределять процессорное время между возможными работа­ми. Сущность «процесс» предполагает, что при диспетчеризации нужно учиты­вать все ресурсы, закрепленные за ним. При манипулировании задачами-потоками можно менять только контекст задачи, если мы переключаемся с одной задачи на другую в рамках одного процесса. Все остальные вычислительные ресурсы при этом не затрагиваются. Каждый процесс всегда состоит, по крайней мере, из одно­го потока выполнения, и только если имеется внутренний параллелизм, програм­мист может «расщепить» один поток на несколько параллельных. Потребность в потоках возникла еще в однопроцессорных вычислительных системах, поскольку они позволяли организовать вычисления более эффективно. Для использования достоинств многопроцессорных систем с общей памятью потоки уже просто необ­ходимы, так как позволяют не только реально ускорить выполнение тех задач, ко­торые допускают их естественное распараллеливание, но и загрузить процессор­ные элементы работой, с тем чтобы они не простаивали. Заметим, однако, что желательно, чтобы можно было свести к минимуму взаимодействие потоков меж­ду собой, ибо ускорение от одновременного выполнения параллельных потоков может быть сведено к минимуму из-за задержек синхронизации и обмена данными.

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

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


40_____________________________________________ Глава 1. Основные понятия

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

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

Для того чтобы можно было эффективно организовать параллельное выполнение рассмотренных сущностей (процессов и потоков), в архитектуру современных про­цессоров включены средства для работы со специальной информационной струк­турой, описывающей ту или иную сущность. Для этого уже на уровне архитектуры микропроцессора используется понятие задача (task). Оно как бы объединяет в себе и обычный процесс, и поток выполнения (тред). Это понятие и поддерживаемая для него на уровне аппаратуры информационная структура позволяют в дальней­шем при разработке операционной системы строить соответствующие дескрипто­ры как для задач, так и для процессов. И отличаться эти дескрипторы будут прежде всего тем, что дескриптор задачи может хранить только контекст приостановлен­ного вычислительного процесса, тогда как дескриптор процесса должен содержать поля, описывающие тем или иным способом ресурсы, выделенные этому процес­су. Для хранения контекста задачи в микропроцессорах с архитектурой i32 имеет­ся специальный сегмент состояния задачи (Task State Segment, TSS). А для отобра­жения информации о процессе используется уже иная информационная структура, однако она включает в себя TSS. Другими словами, сегмент состояния задачи, по­дробно рассматриваемый в разделе «Адресация в 32-разрядных микропроцессо­рах i80x86 при работе в защищенном режиме» главы 4, используется как основа для дескриптора процесса. Таким образом, дескриптор процесса больше по разме­ру, чем TSS, и включает в себя такие традиционные поля, как идентификатор про­цесса, его имя, тип, приоритет и проч.

Каждый поток (в случае использования так называемой «плоской» модели памя­ти — см. раздел «Сегментная, страничная и сегментно-страничная организация памяти» в главе 3) может быть оформлен в виде самостоятельного сегмента, что приводит к тому, что простая (не многопоточная) программа будет иметь всего один сегмент кода в виртуальном адресном пространстве.


Понятия вычислительного процесса и ресурса_______________________________ 41

Теперь, если вернуться к уже упомянутому файлу CONFIG.SYS, в котором для опера­ционной системы OS/2 указываются наиболее важные параметры, определяющие ее работу, стоит заметить, что в этом файле строка THREADS=1024 указывает на ко­личество не процессов, а именно задач. И под задачей в данном случае понимается как процесс, так и поток этого процесса.

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

В завершение можно привести несколько советов по использованию потоков вы­полнения при создании приложений, заимствованных из [28].

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

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

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

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

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


42_____________________________________________ Глава 1. Основные понятия

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

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

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








Дата добавления: 2016-09-20; просмотров: 2454;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.016 сек.