Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Судаков / Лекции / lec15_sinxr.ppt
Скачиваний:
20
Добавлен:
20.03.2015
Размер:
253.44 Кб
Скачать

Блокировки чтения-записи

Несколько операций чтения могут выполняться параллельно с одной и той же переменной

Операции записи должны быть строго последовательными

При записи чтение должно запрещаться

Такую возможность обеспечивает блокировка чтения-записи

Пример использования блокировки чтения-записи

//Общая переменная

//Общая переменная

rw_lock

lock;

rw_lock

lock;

//общий

связанный список

//общий

связанный список

Llist list;

Llist list;

Поток 1

Поток 2

write_lock(&lock);

read_lock(&lock);

//эксклюзивный

//параллельный

//доступ на запись

//доступ на чтение

insert(list);

read(list);

write_unlock(&lock);

read_unlock(&lock);

Пример реализации rw блокировки

int readers=0;

void write_lock(){

int writes=0;

while(1){

Spinlock l;

lock(l);

 

if(!writers && !readers) {

void read_lock(){

writers++;

while(1){

unlock();

lock(l);

break;

if(!writers) {

}

readers++;

unlock(l);

unlock();

}

break;

}

}

 

unlock(l);

Void write_unlock(){

}

lock(l);

}

writers--;

 

unlock(l)

Void read_unlock(){

}

lock(l);

 

readers--;

 

unlock(l)

 

}

 

Отказ обслуживания записи при обслуживании чтения

Пример:

1 поток записи

1000 потоков чтения

Один поток чтения захватывает блокировку

Все потоки чтения ею пользуются

1 поток записи ждет долго!

Реальный пример

Системный таймер

1 поток записывает значение времени в общую переменную

Остальные потоки читают это значение

В нашем случае часы будут отставать

Блокировки чтения-записи с приоритетом на запись

Секвентная блокировка (seq_lock)

Вводится счетчик

Перед началом каждой операции записи значение счетчика увеличивается на 1

После окончания записи значение счетчика снова увеличивается на 1

Вначале и в конце чтения значение счетчика проверяется

Если они четные, то новый акт записи закончен

Если значения одинаковы, то акт записи в процессе чтения не начинался

Использование секвентных блокировок

//Общая переменная time_t time; //Блокировка Seqlock lock;

Поток записи

write_seqlock(lock); time=…;

write_sequnlock(lock)

;

Поток чтения

unsigned long seq;

seq = read_seqbegin(lock);

//считываем время

} while(read_seqretry(&lock,seq));

Реализация seqlock

Spinlock l;

Read_seqbegin(){

Counter c;

return c;

 

}

write_seqlock(){

 

lock(l);

Read_seqretry(int iv){

c++

return (iv & 1) | (c^ iv);

}

}

write_sequnlock(){

 

c++

 

unlock(l);

 

}

 

Недостатки spinlock

Занимают процессорное время

Не могут использоваться для длительного времени ожидания

Семафоры

Семафоры – целочисленные переменные с которыми возможно выполнять атомарные операции увеличения/уменьшения на 1

Если значение семафора становится меньшем нуля, то процесс, который выполнил такую операцию блокируется, пока значение семафора не станет большим или равным нулю

Процессы, ожидающие освобождения семафора не занимают процессорное время

Операции с семафорами

Присвоение значения

Подъем (увеличение на 1) – up()

Опускание (уменьшение на 1) – down()

Требование нулевого значение (есть не во всех реализациях) test()

Считывание значение read()

Все операции атомарные

Соседние файлы в папке Лекции