Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО_ЛАБ_3__15.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
126 Кб
Скачать

3. Семафор

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

CSemaphore semaphore(2,2); //создание семафора. При создании семафора указывается начальное и максимальное значение счетчика

CSingleLock sLock(&semaphore); //Захват семафора

sLock.Lock();

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

sLock.Unlock(); //Освобождение семафора

Пример 1. Рассмотрим консольное приложение, организующее взаимодействие двух потоков, которые задаются попеременным захватом и освобождением мьютексов 1 и 2. Команда cout.flush()переводит строки в поток, предварительно очищая буфер. Общее время обозначено SumTime. Приложение работает до тех пор, пока SumTime < 10000 мкс. Если проект не запускается, то необходимо выполнить следующую последовательность действий:

Проект -> свойства: (самая нижняя строка)-> раскрываем вкладку свойства конфигурации-> Общие. Справа в графе " набор символов" выбираем параметр "не задано"

#include "stdafx.h"

#include <windows.h>

#include <iostream>

#include <fstream>

#include <iomanip>

#include <stdlib.h>

#include <string>

#include <conio.h>

#include <stdio.h>

using namespace std;

int SumTime;

void KeepMutex(HANDLE mutex,int Time); // заголовок функции KeepMutex

void main()

{

int i;

DWORD res;

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

HANDLE mutex1 = CreateMutex(NULL, FALSE, "APPNAME-MTX01");

HANDLE mutex2 = CreateMutex(NULL, FALSE, "APPNAME-MTX01");

srand ((unsigned) time (NULL));// установка псевдослучайного генератораж

// в течение 10 секунд пытаемся попеременно захватывать объекты mutex1 и mutex2

while (SumTime<10000){

cout<<"Trying to get mutex1\n"; cout.flush();//

res = WaitForSingleObject(mutex2,3000);

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

{KeepMutex(mutex1,1000);}; //вызов функции, эмулирующей захват объекта

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

res = WaitForSingleObject(mutex1,20000);

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

{KeepMutex(mutex2,2000);};

cout<<"SumTime="<<SumTime<<"\n\n";

};

cout<<"FINISH!!";

CloseHandle(mutex1);// закрываем дескрипторы

CloseHandle(mutex2);

system("pause");//запрос на завершение работы приложения

};

void KeepMutex(HANDLE mutex,int Time)

{

int T;

T=rand()*Time/(RAND_MAX+1);//расчет текущего времени ожидания

Sleep(T); // ждем

cout<<"Got it! Waiting for mutex"<<"Time="<<T<<"\n"; cout.flush();

cout<<"Now releasing the mutex"<<"\n"; cout.flush();// освобождаем объект

ReleaseMutex(mutex);

SumTime+=T; //пересчет общего времени

}

Задания:

  1. Модифицировать текст программы таким образом, чтобы в ней использовались 3 мьютекса, которые бы удерживали процесс в порядке 1-2-3-1-…

  2. Сократить число мьютексов до одного.

  3. Добавить печать суммарного времени для каждого обработки мьютекса.