shad-go/rwmutex/README.md

42 lines
2.8 KiB
Markdown
Raw Normal View History

2021-03-05 11:58:41 +00:00
## rwmutex
[sync.RWMutex](https://golang.org/pkg/sync/#RWMutex) -- это примитив синхронизации,
предоставляющий доступ к критической секции произвольному количеству читателей,
2021-03-05 13:32:52 +00:00
не более, чем одному писателю. При этом, если есть писатель, то читателей нет.
2021-03-05 11:58:41 +00:00
### Что нужно сделать?
Нужно написать реализацию RWMutex используя каналы.
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
```go
type RWMutex struct {}
func (rw *RWMutex) Lock() {}
func (rw *RWMutex) Unlock() {}
func (rw *RWMutex) RLock() {}
func (rw *RWMutex) RUnlock() {}
```
`RWMutex` можно представлять себе как две блокировки, блокировка на чтение и блокировка на запись.
`New()` возвращает `RWMutex`, в котором ни одна из блокировок не взята.
Процессы, желающие изменить данные (писатели), берут блокировку на запись с помощью метода `Lock`.
Процессы, желающие прочитать данные (читатели), берут блокировку на чтение с помощью метода `RLock`.
По окончании записи писатель отпускает блокировку на запись (`Unlock`).
2021-03-08 12:29:15 +00:00
С блокировкой на чтение связано число активных читателей.
2021-03-05 11:58:41 +00:00
При взятии блокировки (`RLock`) это число инкрементируется.
При завершении чтения (`RUnlock`) блокировка на чтение уменьшает счётчик.
#### Свойства
1. Писатель не заблокируется при взятии блокировки только при условии,
что никакой другой писатель и никакой другой читатель не владеет соответствующей блокировкой.
2. Если какой-то писатель взял блокировку на запись, любой новый писатель или читатель заблокируется при взятии блокировки.
3. Если какой-то читатель взял блокировку на чтение, любой новый писатель заблокируется на взятии блокировки.
2021-03-10 08:14:21 +00:00
Однако любой другой читатель сможет взять блокировку на чтение.
2021-03-05 11:58:41 +00:00
Для выполнения этих свойств достаточно двух каналов.