Мультипрограммирование. Мультипрограммирование в системах разделения времени.. Библиотеки динамической компоновки DLL

Минобрнауки Российской Федерации

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

«ПОВОЛЖСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СЕРВИСА»

Кафедра: « Прикладная информатика в экономике»  

КОНТРОЛЬНАЯ РАБОТА

    По дисциплине: Операционные системы, среды и оболочки

На  тему: Мультипрограммирование. Мультипрограммирование в системах разделения времени.. Библиотеки динамической компоновки DLL 
 
 

  

        Работу  выполнил:

        студент гр. Из-301

        Лобастов  И.В.

        Проверил: Симульман Л.Г. 
         
         
         
         
         
         
         
         

Тольятти, 2012 г

 

      СОДЕРЖАНИЕ 

 

          

ВВЕДЕНИЕ

 

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

 

      

      1. Мультипрограммирование

 

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

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

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

      1) Организация интерфейса между  прикладными программами и ОС  при помощи системных вызовов

      2) Обеспечение средствами коммуникаций  для обмена данными между заданиями

      3) Планирование использования процессора  заключается в организации очереди  из заданий в памяти и выделения  процессора одному из заданий

      4) Создание контекста заданий, т.е.  сохранение содержимого регистра и структуры данных необходимы при выполнении задания при переключение с одного задания на другое

      5) Реализация стратегии управления  памятью, замещения и выборку  информатии из памяти по-скольку память это ограниченные ресурсы

      6) Организация хранения информации  на внешних носителях в виде  файлов и их защита от несанкционированного  доступа

      7) Решение конфликта между конкурирующими  программами и координация программами  своих действий, т.е. обеспечение  синхронизации

      Мультипрограммная система обеспечивает возможность более эффективного использования системных ресурсов, но они ещё долго оставались пакетами. Появление электронных дисплеев решило эту проблему. Логическим  расширением мультипрограммной системы стали системы разделения времени. В них ЦП переключались между заданиями не только во время операции ввода/вывода но и по происшествии определенного времени. эти переключения происходили достаточно часто, чтобы пользователи могли взаимодействовать со своими заданиями во время их выполнения, т.е интерактивно. Появлялась возможность работы нескольких пользователей на одной компьютерной системе. Чтобы уменьшить ограничение на количество пользователей, была использована идея неполного нахождения выполняемой программы в памяти. Основная часть программы находится на диске, а фрагмент, который необходим в данный момент, может быть загружен в ОП, а ненужный выкачан обратно на диск. Это реализуется с помощью механизма виртуальной памяти.

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

1.1. Мультипрограммирование в системах разделения времени

 

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

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

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

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

 

      

      2. БИБЛИОТЕКА ДИНАМИЧЕСКОЙ КОМПОНОВКИ DLL

      Динамические библиотеки DLL (Dynamic Link Library) являютя основой операционной системы Windows. Каждый раз, когда программа осуществляет системный вызов, происходит обращение к функции, расположенной в одной из библиотек DLL. Есть возможность использовать некоторый код, не включая его в тело своей программы на этапе компоновки. Динамическая компоновка обладает тремя основными преимуществами: тело программы занимает меньший объем оперативной памяти, несколько разных программ могут использовать одну и ту же библиотеку, обновление динамической библиотеки не требует заново компоновать программу. Можно создавать собственные динамические библиотеки DLL и использовать их.. Если библиотеку DLL одновременно используют несколько процессов, каждый из них может обладать собственной копией переменных, используемых функциями DLL. Помимо этого, некоторые переменные могут быть общими для всех процессов. Т.о., несколько процессов смогут совместно использовать один и тот же участок оперативной памяти. Этот механизм часто используют для организации обмена данными между процессами. Windows собираясь загрузить DLL в адресное пространство некоторого процесса, прежде всего проверяет, не загружена ли эта же DLL в адресное пространство другого процесса. Если необходимая DLL уже присутствует в ОЗУ, ОС просто пытается отобразить участки памяти, где расположена эта DLL, в адресное пространство обоих процессов, а переменные, индивидуальные для каждого из процессов, не отображаются. Этот метод работает только в случае, если в адресном пространстве второго процесса по адресу, используемому первым процессом для хранения DLL, расположен незанятый участок оперативной памяти. Иначе ОС загрузит библиотеку заново.

      2.1. Использование DLL

 

      Практически невозможно создать приложение Windows, в котором не использовались бы библиотеки DLL. В DLL содержатся все функции Win32 API и несчетное количество других функций операционных систем Win32.

      Вообще  говоря, DLL — это просто наборы функций, собранные в библиотеки. Однако, в отличие от своих статических родственников (файлов . lib), библиотеки DLL не присоединены непосредственно к выполняемым файлам с помощью редактора связей. В выполняемый файл занесена только информация об их местонахождении. В момент выполнения программы загружается вся библиотека целиком. Благодаря этому разные процессы могут пользоваться совместно одними и теми же библиотеками, находящимися в памяти. Такой подход позволяет сократить объем памяти, необходимый для нескольких приложений, использующих много общих библиотек, а также контролировать размеры ЕХЕ-файлов.

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

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

      2.2. Библиотеки импортирования

 

      При статическом подключении DLL имя .lib-файла  определяется среди прочих параметров редактора связей в командной  строке или на вкладке “Link” диалогового  окна “Project Settings” среды Developer Studio. Однако .lib-файл, используемый при неявном подключении DLL, — это не обычная статическая библиотека. Такие .lib-файлы называются библиотеками импортирования (import libraries). В них содержится не сам код библиотеки, а только ссылки на все функции, экспортируемые из файла DLL, в котором все и хранится. В результате библиотеки импортирования, как правило, имеют меньший размер, чем DLL-файлы. К способам их создания вернемся позднее. А сейчас рассмотрим другие вопросы, касающиеся неявного подключения динамических библиотек.

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

      Если  бы мир был совершенен, то программистам  не пришлось бы беспокоиться о согласовании интерфейсов функций при подключении  библиотек — все они были бы одинаковыми. Однако мир далек от совершенства, и многие большие программы  написаны с помощью различных библиотек без C++.

      По  умолчанию в Visual C++ интерфейсы функций  согласуются по правилам C++. Это значит, что параметры заносятся в  стек справа налево, вызывающая программа  отвечает за их удаление из стека при  выходе из функции и расширении ее имени. Расширение имен (name mangling) позволяет редактору связей различать перегруженные функции, т.е. функции с одинаковыми именами, но разными списками аргументов. Однако в старой библиотеке С функции с расширенными именами отсутствуют.

      Хотя  все остальные правила вызова функции в С идентичны правилам вызова функции в C++, в библиотеках С имена функций не расширяются. К ним только добавляется впереди символ подчеркивания (_).

      Если  необходимо подключить библиотеку на С к приложению на C++, все функции  из этой библиотеки придется объявить как внешние в формате С:

         extern "С" int MyOldCFunction(int myParam);

      Объявления  функций библиотеки обычно помещаются в файле заголовка этой библиотеки, хотя заголовки большинства библиотек  С не рассчитаны на применение в проектах на C++. В этом случае необходимо создать копию файла заголовка и включить в нее модификатор extern "C" к объявлению всех используемых функций библиотеки. Модификатор extern "C" можно применить и к целому блоку, к которому с помощью директивы #tinclude подключен файл старого заголовка С. Таким образом, вместо модификации каждой функции в отдельности можно обойтись всего тремя строками:

         extern "С"   {   #include "MyCLib.h"  }

      В программах для старых версий Windows использовались также соглашения о вызове функций языка PASCAL для функций Windows API. В новых программах следует использовать модификатор winapi, преобразуемый в _stdcall. Хотя это и не стандартный интерфейс функций С или C++, но именно он используется для обращений к функциям Windows API. Однако обычно все это уже учтено в стандартных заголовках Windows.

      Загрузка неявно подключаемой DLL

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

  • Каталог, в котором находится ЕХЕ-файл.
  • Текущий каталог процесса.
  • Системный каталог Windows.

      Если  библиотека DLL не обнаружена, приложение выводит диалоговое окно с сообщением о ее отсутствии и путях, по которым осуществлялся поиск. Затем процесс отключается.

      Если  нужная библиотека найдена, она помещается в оперативную память процесса, где  и остается до его окончания. Теперь приложение может обращаться к функциям, содержащимся в DLL.

      Динамическая загрузка и выгрузка DLL

      Вместо  того, чтобы Windows выполняла динамическое связывание с DLL при первой загрузке приложения в оперативную память, можно связать программу с  модулем библиотеки во время выполнения программы (при таком способе в процессе создания приложения не нужно использовать библиотеку импорта). В частности, можно определить, какая из библиотек DLL доступна пользователю, или разрешить пользователю выбрать, какая из библиотек будет загружаться. Таким образом можно использовать разные DLL, в которых реализованы одни и те же функции, выполняющие различные действия. Например, приложение, предназначенное для независимой передачи данных, сможет в ходе выполнения принять решение, загружать ли DLL для протокола TCP/IP или для другого протокола.

      2.3. Загрузка обычной DLL

 

      Первое, что необходимо сделать при динамической загрузке DLL, - это поместить модуль библиотеки в память процесса. Данная операция выполняется с помощью  функции ::LoadLibrary, имеющей единственный аргумент – имя загружаемого модуля. Соответствующий фрагмент программы должен выглядеть так:

         HINSTANCE hMyDll;  ……  if((hMyDll=::LoadLibrary

      (“MyDLL”))==NULL) { /* не удалось загрузить DLL */ }

            else { /* приложение  имеет право

        пользоваться функциями DLL через hMyDll */ }

      Стандартным расширением файла библиотеки Windows считает .dll, если не указать другое расширение. Если в имени файла  указан и путь, то только он будет  использоваться для поиска файла. В  противном случае Windows будет искать файл по той же схеме, что и в случае неявно подключенных DLL, начиная с каталога, из которого загружается exe-файл, и продолжая в соответствии со значением PATH.

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

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

      Перед тем, как использовать функции библиотеки, необходимо получить их адрес. Для этого  сначала следует воспользоваться  директивой typedef для определения типа указателя на функцию и определить переменую этого нового типа, например:

         // тип PFN_MyFunction будет объявлять указатель

                   на функцию, 

            // принимающую указатель  на символьный буфер

        и выдающую значение типа int  typedef int

        (WINAPI *PFN_MyFunction)(char *);

            ……  PFN_MyFunction pfnMyFunction;

      Затем следует получить дескриптор библиотеки, при помощи которого и определить адреса функций, например адрес фунции с именем MyFunction:

         hMyDll=::LoadLibrary(“MyDLL”);

            pfnMyFunction=(PFN_MyFunction)::GetProcAddress

                                 (hMyDll,”MyFunction”);

            ……  int iCode=(*pfnMyFunction)(“Hello”);

      Адрес функции определяется при помощи функции ::GetProcAddress, ей следует передать имя библиотеки и имя функции. Последнее должно передаваться в том виде, в котором эксаортируется из DLL.

      Можно также сослаться на функцию по порядковому номеру, по которому она экспортируется (при этом для создания библиотеки должен использоваться def-файл, об этом будет рассказано далее):

         pfnMyFunction=(PFN_MyFunction)::GetProcAddress

      (hMyDll,     MAKEINTRESOURCE(1));

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

      2.4. Пример неявного  подключения DLL приложением

 

      Приведем  теперь исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll:

        #include <windows.h>  #include “MyDLL.h”int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,    LPSTR lpCmdLine,

       int nCmdShow)  {   int iCode=MyFunction(“Hello”);

                  return 0;  }

      Эта программа выглядит как обычная программ для Windows, чем она в сущности и является. Тем не менее, следует обратить внимание, что в исходный ее текст помимо вызова функции MyFunction из DLL-библиотеки включен и заголовочный файл этой библиотеки MyDLL.h. Также необходимо на этапе компоновки приложения подключить к нему библиотеку импорта MyDLL.lib (процесс неявного подключения DLL к исполняемому модулю).

      Чрезвычайно важно понимать, что сам код  функции MyFunction не включается в файл MyApp.exe. Вместо этого там просто имеется  ссылка на файл MyDLL.dll и ссылка на функцию MyFunction, которая находится в этом файле. Файл MyApp.exe требует запуска файла MyDLL.dll.

      Заголовочный  файл MyDLL.h включен в файл с исходным текстом программы MyApp.c точно так  же, как туда включен файл windows.h. Включение библиотеки импорта MyDLL.lib для компоновки аналогично включению туда всех библиотек импорта Windows. Когда програма MyApp.exe работает, она подключается к библиотеке MyDLL.dll точно так же, как ко всем стандартным динамически подключаемым библиотекам Windows.

      2.5. Пример динамической  загрузки DLL приложением

 

      Приведем  теперь полностью исходный код простого приложения, которое использует функцию MyFunction из библиотеки MyDLL.dll, используя  динамическую загрузку библиотеки:

         #include <windows.h>  typedef int

      (WINAPI *PFN_MyFunction) (char *);   int WINAPI

      WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

                        LPSTR lpCmdLine, int nCmdShow)

            {   HINSTANCE hMyDll;

                  if((hMyDll=LoadLibrary(“MyDLL”))==NULL) return 1; 

                  PFN_MyFunction pfnMyFunction;

                  pfnMyFunction=(PFN_MyFunction)

                 GetProcAddress(hMyDll,”MyFunction”);

                  int iCode=(*pfnMyFunction)(“Hello”);

                  FreeLibrary(hMyDll);   return 0;  }

      Теперь, познакомившись с принципами работы библиотек DLL в  приложениях, рассмотрим способы их создания. При разработке приложении функции, к которым обращается несколько процессов, желательно размещать в DLL. Это позволяет более рационально использовать память в Windows.

      Проще всего создать новый проект DLL с помощью мастера AppWizard, который  автоматически выполняет многие операции. Для простых DLL, таких как рассмотренные в этой главе, необходимо выбрать тип проекта Win32 Dynamic-Link Library. Новому проекту будут присвоены все необходимые параметры для создания библиотеки DLL. Файлы исходных текстов придется добавлять к проекту вручную.

      Если  же планируется в полной мере использовать функциональные возможности MFC, такие  как документы и представления, или намерены создать сервер автоматизации OLE, лучше выбрать тип проекта MFC AppWizard (dll). В этом случае, помимо присвоения проекту параметров для подключения динамических библиотек, мастер проделает некоторую дополнительную работу.

 

      

      3. Практическая часть

 

      Задание: Создайте командный файл резервного копирования файлов с определенными расширениями из разных каталогов с возможностью создания резервного каталога, если его нет в системе.

      Ход выполнения работы:

  1. Создаём командный файл с названием kp.bat
  2. Далее с помощью блокнота вписывает в него следующие команды:

      echo on

      IF NOT exist kp md kp  - команда создаст каталог kp при условии что его нету в системе.

      cd kp -

      md s –

        md f -

      cd ..-

      copy project\*.doc kp\s -

      copy project\*.txt kp\f

      copy project1\*.doc kp\s

      copy Project1\*.txt kp\f

  1. Сохраняем изменения и запускаем комадный файл kp.bat 

Заключение

 

      При выполнении этой контрольной работы я узнал что такое Мультипрограммирование и его виды. Его появление привело  к росту эффективности работы процессора а так же позволяет выполнять несколько задач сразу. Узнал что такое DLL файлы, для чего они нужны и способы их загрузки. Так же научился создавать командные файлы резервного копирования файлов.

Мультипрограммирование. Мультипрограммирование в системах разделения времени.. Библиотеки динамической компоновки DLL