АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

Читайте также:
  1. AutoCAD 2005. Общие сведения
  2. I. Общие сведения
  3. I. Общие сведения
  4. I. ОБЩИЕ СВЕДЕНИЯ О ХОЗЯЙСТВЕ
  5. II. Общие теоретические сведения о шуме
  6. III. Сведения авторов VI-VII вв.
  7. IV. ОБЩИЕ СВЕДЕНИЯ О ВСЕРОССИЙСКОМ СЕМИНАРЕ.
  8. XIII. Сведения о соблюдении Обществом кодекса корпоративного поведения
  9. Базовые теоретические сведения
  10. Валы и оси. Общие сведения. Характеристика, классификации, материалы, термообработка.
  11. Ввод-вывод. Общие сведения
  12. Вместо заключения (теоретические пояснения)

Изучение возможностей использования семафоров в Windows

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

 

КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

 

Семафор – это объект синхронизации, который позволяет ограничить доступ потоков к объекту синхронизации на основании их количества. Например, необходимо чтобы к какому-нибудь объекту могли обратиться максимум 3 потока. Не больше. Тогда нам нужен семафор. Сначала семафор инициализируется и ему передается количество потоков, которые к нему могут обратиться. Дальше при каждом обращении к ресурсу его счетчик уменьшается. Когда счетчик уменьшиться до 0 к ресурсу обратиться больше нельзя. При отсоединении потока от семафора его счетчик увеличивается, что позволяет другим потокам обратиться к нему. Сигнальному состоянию соответствует значение счетчика больше нуля. Когда счетчик равен нулю, семафор считается не установленным (сброшенным).

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

Таким образом, для семафоров определены следующие правила работы:

1. Семафор переходит в сигнальное состояние, если значение счетчика ресурсов больше 0.

2. Семафор занят, если значение счетчика равно 0.

3. Не допускается установка отрицательного значения счетчика.

4. Счетчик не может иметь значение, большее максимального числа ресурсов.

 

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

HANDLE CreateSemaphore (

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

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

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

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

 

Получить описатель существующего семафора можно с помощью функции

HANDLE OpenSemaphore (

DWORD dwAccess, // режим доступа

BOOL bInherit, // наследование

LPCTSTR lpName); // Символьное имя объекта

 

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

BOOL ReleaseSemaphore (

HANDLE hSemaphore,// хендл (описатель объекта) семафора

LONG lReleaseCount, // насколько увеличить счетчик ресурсов (обычно 1)

LPLONG lpPreviousCount);// предыдущее значение (обычно NULL)

 

При успешном выполнении возвращаемое значение ненулевое. Для уничтожения семафора нужно вызвать CloseHandle()

 

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

HANDLE Semaphore; LONG Max = 12, PreviousCount;

// создание семафора с одинаковыми значениями счетчиков равными 12

Semaphore = CreateSemaphore(NULL, cMax, cMax, NULL);

// безымянный семафор

if (Semaphore == NULL)

{ // проверка ошибок }

 

Пример приложения использующего функции WinAPI для роботы с семафором.

 

1. Создайте консольное приложение в среде MS Visual Studio.NET, как это показано на рисунке 1. При этом обязательно поставьте галочку использовать MFC.

 

Рисунок 1. Создание консольного приложения

 

2. Замените сгенерированный программный код следующим.

 

Листинг 1.Использование семафора.

#include "stdafx.h"

#include "windows.h"

#include "process.h"

 

HANDLE hSemaphore;

LONG cMax = 2;

 

void Test1(void *);

void Test2(void *);

void Test3(void *);

 

 

// The one and only application object

 

CWinApp theApp;

 

using namespace std;

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

int nRetCode = 0;

 

// initialize MFC and print and error on failure

if (!AfxWinInit(::GetModuleHandle(NULL), NULL,::GetCommandLine(), 0))

{

// TODO: change error code to suit your needs

_tprintf(_T("Fatal Error: MFC initialization failed\n"));

nRetCode = 1;

}

else

{

 

 

hSemaphore = CreateSemaphore(

NULL,// нет атрибута

cMax,// начальное состояние

cMax,// максимальное состояние

NULL// без имени

);

 

if (!hSemaphore == NULL)

{

if (_beginthread(Test1,1024,NULL)==-1)

printf ("Error begin thread \n");

 

 

if (_beginthread(Test3,1024,NULL)==-1)

printf ("Error begin thread \n");

 

if (_beginthread(Test2,1024,NULL)==-1)

printf ("Error begin thread \n");

 

Sleep(100000);

CloseHandle(hSemaphore);

}

else

{

printf("error create semaphore\n");}

}

 

 

return nRetCode;

}

 

 

void Test1(void *)

{

 

printf ("Test1 Running\n");

DWORD dwWaitResult;

do

{

dwWaitResult = WaitForSingleObject(

hSemaphore,// указатель на семафор

1// интерфал ожидания

);

printf ("Test 1 TIMEOUT\n");

}while(dwWaitResult==WAIT_OBJECT_0);

Sleep(1000);

if (ReleaseSemaphore(

hSemaphore,// указатель на семафор

1,// изменяет счетчик на 1

NULL)

)

printf(" ReleaseSemaphore Ok Test1\n");

_endthread();

}

 

void Test2(void *)

{

DWORD dwWaitResult;

printf ("Test2 Running\n");

do

{

dwWaitResult = WaitForSingleObject(hSemaphore,1);

printf("Test 2 TIMEOUT\n");

}while(dwWaitResult==WAIT_OBJECT_0);

Sleep(1000);

if (ReleaseSemaphore(hSemaphore,1,NULL))

printf("ReleaseSemaphore Ok Test2\n");

_endthread();

}

 

void Test3(void *)

{

printf ("Test3 Running\n");

DWORD dwWaitResult;

do

{

dwWaitResult = WaitForSingleObject(hSemaphore,1);

printf ("Test 3 TIMEOUT\n");

}while(dwWaitResult==WAIT_OBJECT_0);

Sleep(1000);

if (ReleaseSemaphore(hSemaphore,1,NULL))

printf (" ReleaseSemaphore Ok Test3\n");

_endthread();

}

 

3. Создайте исполнимый файл и запустите его. В Результате у вас должно появится следующее окно:

 

 

4. Внимательно изучите работу приложения и выполните нижеследующее задание.

 


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



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.)