Добавил:
Факультет ИКСС, группа ИКВТ-61 Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LAB / Миронов / Lab_8

.docx
Скачиваний:
29
Добавлен:
20.02.2019
Размер:
50.86 Кб
Скачать

ФЕДЕРАЛЬНОЕ АГЕНТСТВО СВЯЗИ

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

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА»

(СПбГУТ)

ОТЧЁТ

по лабораторной работе №8 на тему: «Синхронизация процессов под Windows»

по дисциплине «Операционные системы»

Выполнили: студенты группы ИКВТ-61, Миронов П.В., Гарифулина Т.С.

Принял: доцент кафедры ПИиВТ Дагаев А.В.

Цель: разработать многопоточное приложение под Windows.

Средства: Для выполнения данной работы использовались: Операционная система Windows 10, Microsoft Visual C++.

Основные определения:

  1. Процесс – это некоторая часть работы ОС, обладающая уникальным идентификационным номером – id,  и адресное пространство.  Адресное пространство – некоторый список адресов в памяти, с которыми происходит работа этого процесса. С другими адресами процессу приходится работать через системный вызов. Одна программа может включать как несколько процессов, так и один, причем последнее используется наиболее часто. Разбиение на процессы позволяет распараллелить задачи, благодаря чему ускорить работу, но в большинстве случаев для этого проще и выгоднее использовать потоки, которые намного быстрее взаимодействуют друг с другом и обладают рядом других положительных моментов, что и привело к меньшей используемости процессов.

  2. Поток – это часть уже самого процесса, выполняющая определенный список действий. У каждого процесса есть как минимум один поток, и их увеличение обеспечивает распараллеливание процесса. Чем выгодней такое  увеличение потоков внутри процесса увеличения количества самих процессов? Каждый поток, как часть процесса, имеет доступ ко всему адресному пространству процесса, ко всем его устройствам и переменным. Поэтому взаимодействие двух отдельных потоков реализуется очень просто и не требует обращения к системе. По этой причине использование потоков более распространено, чем процессов.

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

  4. Мьютекс — аналог критической области, позволяющий синхронизировать потоки в разных процессах. Критическая область идентифицировалась переменной типа CRITICAL_SECTION, которая использовалась потоками совместно. У процессов не может быть общей переменной, поэтому мьютексам присваиваются имена при создании. Сначала поток одного из процессов создает мьютекс функцией CreateMutex(); потоки остальных процессов получают доступ к этому мьютексу функций OpenMutex() по известному имени мьютекса.

Теоретическая часть:

Чтобы создать тот или иной объект синхронизации, производится вызов специальной функции WinAPI типа Create... (напр. CreateMutex). Этот вызов возвращает дескриптор объекта (HANDLE), который может использоваться всеми потоками, принадлежащими данному процессу. Есть возможность получить доступ к объекту синхронизации из другого процесса - либо унаследовав дескриптор этого объекта, либо, что предпочтительнее, воспользовавшись вызовом функции открытия объекта (Open...). После этого вызова процесс получит дескриптор, который в дальнейшем можно использовать для работы с объектом. Объекту, если только он не предназначен для использования внутри одного процесса, обязательно присваивается имя. Имена всех объектов должны быть различны (даже если они разного типа). Нельзя, например, создать событие и семафор с одним и тем же именем.

По имеющемуся дескриптору объекта можно определить его текущее состояние. Это делается с помощью т.н. ожидающих функций. Чаще всего используется функция WaitForSingleObject. Эта функция принимает два параметра, первый из которых - дескриптор объекта, второй - время ожидания в мсек. Функция возвращает WAIT_OBJECT_0, если объект находится в сигнальном состоянии, WAIT_TIMEOUT - если истекло время ожидания, и WAIT_ABANDONED, если объект-взаимоисключение не был освобожден до того, как владеющий им поток завершился. Если время ожидания указано равным нулю, функция возвращает результат немедленно, в противном случае она ждет в течение указанного промежутка времени. В случае, если состояние объекта станет сигнальным до истечения этого времени, функция вернет WAIT_OBJECT_0, в противном случае функция вернет WAIT_TIMEOUT.

Ход работы:

  1. Листинг программы:

  1. #include <windows.h>

  2. #include <iostream>

  3. using namespace std;

  4. void main()

  5. {

  6. DWORD res;

  7. // создаем объект-взаимоисключение

  8. HANDLE mutex = CreateMutex(NULL, FALSE, "IKVT_61");

  9. // если он уже существует, CreateMutex вернет дескриптор существующего

  10. // объекта, а GetLastError вернет ERROR_ALREADY_EXISTS

  11. // в течение 20 секунд пытаемся захватить объект

  12. cout << "Trying to get mutex...\n"; cout.flush();

  13. res = WaitForSingleObject(mutex, 20000);

  14. if (res == WAIT_OBJECT_0) // если захват удался

  15. {

  16. // ждем 10 секунд

  17. cout << "Got it! Waiting for 10 secs...\n"; cout.flush();

  18. Sleep(10000);

  19. // освобождаем объект

  20. cout << "Now releasing the object.\n"; cout.flush();

  21. ReleaseMutex(mutex);

  22. }

  23. // закрываем дескриптор

  24. CloseHandle(mutex);

  25. }

  1. Результат выполнения

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

Вывод: выполняя данную лабораторную работу, мы получили навыки в работе с синхронизацией процессов.

САНКТ-ПЕТЕРБУРГ 2018

Соседние файлы в папке Миронов