- Всем попадает в одну строку
- Группы читателей, смежные по строке, получают одновременный доступ
- Писатель ждет всех читателей перед ним, а затем получает доступ
- li>
После того как автор разблокируется, доступ получает следующая непрерывная группа читателей.
Код: Выделить всё
// SharedTicketLock.h
#pragma once
#include
#include
class SharedTicketLock {
std::atomic next_ticket{0};
std::atomic now_serving{0};
std::atomic served{0};
public:
void writer_lock(){
uint16_t my_ticket = next_ticket.fetch_add(2);
while (now_serving.load() != my_ticket || now_serving.load() != served.load()){
std::this_thread::yield();
}
}
void reader_lock(){
uint16_t my_ticket = next_ticket.fetch_add(1);
while (now_serving.load() != my_ticket){
std::this_thread::yield();
}
now_serving.fetch_add(1);
}
void writer_unlock(){
now_serving.fetch_add(2);
served.fetch_add(2);
}
void reader_unlock(){
served.fetch_add(1);
}
};
- Мы добавляем дополнительный атомный счетчик к традиционной блокировке билетов: обслуживается для отслеживания количества читателей в критическом разделе.
- Писатели берут два билета: next_ticket.fetch_add(2), а читатели — только один.
- Читатели входят, когда now_serving равно my_ticket.
- Писатели вводят, когда now_serving равно my_ticket, а также когда now_serving равняется обработанному, указывая все предыдущие участники покинули критический раздел.
- Когда считыватель блокируется, он немедленно увеличивает значение now_serving, которое в этой реализации используется для определения текущих считывателей и сигналов для следующему участнику, что, если он читатель, он может войти. Если следующим участником является писатель, он должен дождаться, пока now_serving и обслуживается сравняются.
- Когда писатель блокируется, он не увеличивает now_serving
- Когда писатель блокируется, он не увеличивает now_serving
- code>, создавая разрыв в два билета между участником и писателем и заставляя всех ждать.
- Когда читатель разблокируется, объем обслуживания увеличивается, который используется писателями. чтобы знать, когда все читатели до подсчета билетов ушли.
- Когда писатель разблокируется, он дважды увеличивает как next_ticket, так и now_serving, сигнализируя следующему участнику, что автор покинул критический раздел, и теперь он может войти.
- Если следующие участники — читатели, они все войдут, поскольку каждый из них увеличивает now_serving и проверяет наличие 1 билета разрыв.
- Переполнение заявки обрабатывается неявно, поскольку выполняются только проверки на равенство.
Подробнее здесь: https://stackoverflow.com/questions/791 ... icket-lock