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

4.4. Условные переменные

Когда сам разработчик ОС создает буфер, то все ресурсы для управления процессами ему доступны.

Т.е. ему доступны следующие ресурсы:

  1. Очереди процессов, в том числе и очередь готовых процессов;

  2. Дескрипторы процессов, в том числе известно, какой из процессов является текущим процессом;

  3. Функция для передачи управления от одного процесса к другому процессу;

  4. Команды запрета и разрешения прерываний.

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

Если может, то он это делает, разрешает прерывания и выходит из функции.

Если нет, то процесс встает в очередь буфера, выбирает из очереди готовых процессов новый процесс для выполнения и передает ему управление с одновременным разрешением прерываний. Т.е. процесс блокируется, но освобождает прерывания, давая другим работать.

Для программирования параллельных процессов в рамках какой-нибудь существующей ОС такие действия недоступны.

Для защиты критических ресурсов доступны только мьютексы, а дескрипторы, очереди, прерывания и передачи управления недоступны.

И вот здесь приходит на помощь средство, которое называется «условные переменные».

Условная переменная – это объект, над которым процесс может выполнить одну из трех операций:

  1. Заблокироваться с одновременным освобождением мьютекса (переданного в качестве параметра);

  1. Разблокировать один из заблокированных (на этой условной переменной) процессов (не известно, какой);

  1. Разблокировать все заблокированные на этой условной переменной процессы.

По сути, условная переменная представляет собой очередь процессов, но определенные процессы из этой очереди недоступны.

Одновременная разблокировка всех процессов накладывает определенную специфику на условие блокирования. Надо заставить все процессы опять проверить условие блокировки. В результате «гонок» один процесс пойдет дальше, а остальные опять заблокируются.

Ниже представлен вариант реализации буфера на условных переменных в сопоставлении с ранее рассмотренным вариантом.

TProcess curproc;

TList ReadyList;

void swt(TProcess from,TProcess to);

int in;

int out;

int n;

char Buf[N];

TList ReadList;

TList WriteList;

void Write(char M);

char Read();

void Write(char M)

{

запретить_прерывания();

TProcess oldproc;

if (n == N) {//буфер полный

oldproc = curproc;

WriteList.insert(oldproc);

curproc = ReadyList.at(0);

ReadyList.remove(curproc);

swt(oldproc,curproc);

}

n++;

Buf[in] = M;

in = (in + 1) % N;

if (ReadList.getCount() > 0) {

oldproc = curproc;

ReadyList.insert(oldproc);

curproc = ReadList.at(0);

ReadList.remove(curproc);

swt(oldproc,curproc);

}

разрешить_прерывания();

}

char Read()

{

запретить_прерывания();

TProcess oldproc;

if (n == 0) {//буфер пустой

oldproc = curproc;

ReadList.insert(oldproc);

curproc = ReadyList.at(0);

ReadyList.remove(curproc);

swt(oldproc,curproc);

}

n--;

char М = Buf[out];

out = (out + 1) % N;

if (Writeist.getCount() > 0) {

oldproc = curproc;

ReadyList.insert(oldproc);

curproc = WriteList.at(0);

WriteList.remove(curproc);

swt(oldproc,curproc);

}

разрешить_прерывания();

return M;

}

«Буфер» на условных переменных

int in;

int out;

int n;

char Buf[N];

TCondVar ReadCondVar;

TCondVar WriteCondVar;

Tmutex mutex;

void Write(char M);

char Read();

void Write(char M)

{

mutex.lock();

while (n == N) {//пока буфер полный

WriteCondVar.wait(mutex);

}

n++;

Buf[in] = M;

in = (in + 1) % N;

ReadCondVar.signal();

mutex.unlock();

}

char Read()

{

mutex.lock();

while (n == 0) {//пока буфер пустой

ReadCondVar.wait(mutex);

}

n--;

char М = Buf[out];

out = (out + 1) % N;

WriteCondVar.signal();

mutex.unlock();

return M;

}

Соседние файлы в предмете Операционные системы