Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
25
Добавлен:
17.04.2013
Размер:
83.46 Кб
Скачать

Class Semaphore {

int count;

ThreadDescriptor* queue;

Pubic:

Semaphore(int n) { count = n; queue = null; }

Void P();

Void V();

};

void Semaphore::P() { void Semaphore::V() {

If(count>0) count--; if(queue не пуста) {

else { //Один в очередь готовых

//Поставить в очередь queue }

// Позвать планировщик else

} count++;

} }

Двоичный семафор:Начальное значение переменной семафора равно 1. ОперацияPставит процесс в очередь, если значение переменной семафора 0, сбрасывает переменную в 0, если она равнялась 1. ОперацияVосвобождает один процесс из очереди к семафору, если очередь не пуста. Если очередь пуста, то присваивает переменной семафора 1.

Применение семафора

Взаимное исключение

// Начальное значение счетчика семафора 1.

P();

Критическая секция;

V();

Ожидание некоторого события

P() – при нулевом начальном значении будет ждать, пока кто-то другой сообщит о наступлении события выполнив операциюV().

Задача о «производителе и потребителе»

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

Условия синхронизации:

  1. Производитель должен ждать, если буфер полон.

  2. Потребитель должен ждать, если буфер пуст.

  3. Операции с буфером – критическая секция, т.е. работать с буфером может только один процесс.

Правило большого пальца:число семафоров, необходимое для решения задачи равно числу условий синхронизации.

int size = 10;

Semaphore mutex(1);

Semaphore fill(0);

Semaphore empty(size);

void Producer() { Void Consumer() {

// Подготовить data fill.P();

empty.P(); mutex.P();

mutex.P(); RemoveFromBuffer(&data);

AddToBuffer(data); mutex.V();

mutex.V(); empty.V();

fill.V(); // Обработать data

} }

Вопросы:

  • Важен ли порядок Pопераций?

  • Важен ли порядок Vопераций?

  • Нужны ли изменения для 2 производителей и 2 потребителей?

Реализация семафоров для многопроцессорных машин p: V:

// Запрет прерываний // Запрет прерываний

while(test&set(v)==1); while(test&set(v)==1);

if(count>0) { if(очередь пуста) {

count--; count++;

v = 0; } else {

// разрешить прерывания // взять одного из очереди

return; // и в очередь готовых

} }

// поставить в очередь v = 0;

v = 0; // разрешить прерывания

Вызвать планировщик

Счетчик событий

Аналогичен семафорам, реализуется на основе следующих примитивов:

Read(E) - получить значение счетчика

Advance(E) - Увеличить счетчик на 1

Wait(E,v) - ждать покаE < v

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