Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Синхронизация процессов и потоков





Семафор – объект синхронизации, который может регулировать доступ к некоторому ресурсу. Мьютекс – переменная, которая может находиться в одном из двух состояний: блокированном или неблокированном. Мьютекс может охранять неразделенный ресурс, к которому в каждый момент времени допускается только один поток, а семафор может охранять ресурс, с которым может одновременно работать не более N потоков.

Мьютексный объект создается функцией:

Функция CreateMutex

HANDLE CreateMutex

(

LPSECURITY_ATTRIBUTES lpMutexAttributes, // атрибут безопастности

BOOL bInitialOwner, // флаг начального владельца

LPCTSTR lpName // имя объекта

);

Функция возвращает дескриптор мьютексного объекта с именем, заданным параметром lpName. Имя мьютекса не должно совпадать с именем уже существующего события, семафора и других объектов межпроцессной синхронизации.

Функция GetLastError при вызове будет выдавать

ERROR_ALREADY_EXISTS.

Для открытия существующего мьютекса используется функция OpenMutex, освобождения – ReleaseMutex.

Семафор создается функцией:

Функция CreateSemaphore

HANDLE CreateSemaphore

(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // атрибут доступа

LONG lInitialCount, // инициализированное начальное

// состояние счетчика

LONG lMaximumCount, // максимальное количество

// обращений

LPCTSTR lpName // имя объекта

);

При успешном выполнении функция вернет идентификатор семафора, в противном случае NULL. После того как необходимость в работе с объектом отпала нужно вызвать функцию ReleaseSemaphore, чтобы освободить счетчик. Для открытия существующего семафора используется функция OpenSemaphore.

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

Функция WaitForSingleObject

DWORD WaitForSingleObject

(

HANDLE hHandle,

DWORD dwMilliseconds

);

Здесь первый параметр – дескриптор объекта синхронизации, а второй – время ожидания в миллисекундах. Для ожидания нескольких синхронизирующих объектов используется функция WaitForMultipleObjects.

В листинге 18 приведен пример программы использования мьютекса. При запуске программы она создает объект с именем «MMM», если захватить его удается WaitForSingleObject, то программа выполняется якобы, ждет пока введете число и нажмете Enter. Если захватить его не удается, то выходит с надписью fail.

Если Вы попробуете, то Вы сможете запустить только одну копию.

#include "windows.h"

#include "iostream.h"

void main()

{

HANDLE mut;

mut = CreateMutex(NULL, FALSE, "MMM");

DWORD result;

result = WaitForSingleObject(mut,0);

if (result == WAIT_OBJECT_0)

{

cout << "programm running" << endl;

int i;

cin >> i;

ReleaseMutex(mut);

}

else

cout << "fail programm running" << endl;

CloseHandle(mut);

}

Листинг 18 – Пример использования мьютекса

Задание:

1. Написать программы с требованиями:

– может запуститься только один экземпляр приложения, для определения

запущено приложение или нет использовать мьютекс (проверка, не создан ли

мьютекс предыдущим экземпляром);

– запускаются два экземпляра программы, при нажатии на кнопку первого

экземпляра эмулируется захват ресурса и устанавливается мьютекс, второй

экземпляр, при нажатии на кнопку ожидает с использованием функции

WaitForMultipleObjects освобождение ресурса в течении 3 секунд и, если ресурс

освобождается, то он захватывается 2-ым экземпляром, в противном случае

выводится на экран невозможность захвата ресурса;

– может запуститься только 4 экземпляра одного приложения, реализация с

использованием семафора.

Контрольные вопросы:

1. Для чего нужны объекты синхронизации?

2. Чем отличается мьютекс от семафора?

3. Как работает функция CreateSemaphore?

4. Для чего нужны функции ожидания?

5. Чем отличаются функции WaitForSingleObject и WaitForMultipleObjects?

Для самостоятельного изучения:

1. Функции OpenMutex, OpenSemaphore, WaitForMultipleObjects.

2. Объекты событий.

3. Таймеры ожидания.

Управление памятью

Для управления памятью в операционной системе Windows предусмотрен ряд функций.

Функция GlobalAlloc

HGLOBAL GlobalAlloc

(

UINT uFlags,

SIZE_T dwBytes

);

Функция выделяет из глобальной кучи память запрошенного размера.

Параметры:

uFlags – маска флагов.

dwBytes – размер выделяемой памяти

Возвpащаемое значение:

Идентификатоp выделенного блока глобальной памяти; 0 - если ошибка.

В листинге 19 пример вызова функции Windows для выделения блока памяти для указателя на целые.

DWORD dwSize = 1024;

UINT uiFlags = 0;

p = (int *)GlobalAlloc(uiFlags, dwSize);

Листинг 19 – Выделение памяти с помощью GlobalAlloc

За исключением одной, для каждой функции, начинающейся со слова Global, существует другая, начинающаяся со слова Local. Эти два набора функций в Windows идентичны. Два различных слова сохранены для совместимости с предыдущими версиями Windows, где функции Global возвращали дальние указатели, а функции Local – ближние. Если первый параметр задать нулевым, то это эквивалентно использованию флага GMEM_FIXED. Такой вызов функции

GlobalAlloc эквивалентен вызову функции malloc.

Следующий пример демонстрирует использование функции изменения размера блока памяти:

p = (int *)GlobalReAlloc(p, dwSize, uiFlags);

Для определения размера выделенного блока памяти используется функція

GlobalSize:

dwSize = GlobalSize(p);

Функция освобождения памяти:

GlobalFree(p);

Функция GlobalAlloc поддерживает флаг GMEM_MOVEABLE и комбинированный флаг для дополнительного обнуления блока памяти (описано в заголовочных файлах Windows):

#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT)

Флаг GMEM_MOVEABLE позволяет перемещать блок памяти в виртуальной памяти, при этом функция возвращает не адрес выделенного блока, а 32-разрядный описатель (дескриптор) блока памяти. Это необязательно означает, что блок памяти будет перемещен в физической памяти, но адрес, которым пользуется программа для чтения и записи, может измениться. Для фиксации блока используется вызов:

p =(int *)GlobalLock(hGlobal);

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

GlobalUnlock(hGlobal);

Этот вызов дает Windows свободу перемещать блок в виртуальной памяти.

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

Если в данный момент нет доступа к описателю, то необходимо использовать функцию:

hGlobal = GlobalHandle(p);

Для преднамеренного удаления блока памяти можно использовать следующий вызов:

GlobalDiscard(hGlobal);

Другим доступным для использования в функции GlobalAlloc является флаг GMEM_SHARE или GMEM_DDESHARE (идентичны). Как следует из его имени, этот флаг предназначен для динамического обмена данными. Функции GlobalAlloc и GlobalReAlloc могут также включать флаги GMEM_NODISCARD и GMEM_NOCOMPACT.

Эти флаги дают указание Windows не удалять и не перемещать блоки памяти для удовлетворения запросов памяти.

Функция GlobalFlags возвращает комбинацию флагов GMEM_DISCARDABLE, GMEM_DISCARDED и GMEM_SHARE.

Наконец, вы можете вызвать функцию GlobalMemoryStatus (для этой функции нет функции – двойника со словом Local) с указателем на структуру типа MEMORYSTATUS для определения количества физической и виртуальной памяти, доступной приложению.

Windows также поддерживает некоторые функции, реализованные программистом или дублирующие библиотечные функции C. Это функции

FreeMemory (заполнение конкретным байтом),

ZeroMemory (обнуление памяти),

CopyMemory и MoveMemory – обе копируют данные из одной области памяти в другую. Если эти области перекрываются, то функция CopyMemory может рабо тать некорректно. Вместо нее используйте функцию MoveMemory.

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

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

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

Следует начинать с вызова функции HeapCreate. Затем, использовать функции HeapAllocate, HeapReAllocate и HeapFree для выделения и освобождения блоков памяти в рамках «кучи».

Задание:

1. Написать программу:

– средствами Win32 API выделяющая память для массива размерностью M на

N, размерность вводится с клавиатуры;

– случайным образом заполняется весь массив информацией;

– необходимо в каждой строке найти элемент с наименьшим значением, а

затем среди этих чисел найти наибольшее. На экран вывести индексы этого

элемента, а также все элементы матрицы.

Контрольные вопросы:

1. Какие средства поддерживает язык C/C++ для управления памятью?

2. Назовите основные флаги функции GlobalAlloc и их назначение?

3. Чем отличаются функции Global и Local?

4. Какими функциями предпочтительнее выделять память для функций Win32API?

Для самостоятельного изучения:

1. Методы C/C++ выделения памяти.







Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам...

Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом...

ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между...

Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычис­лить, когда этот...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.