42 lines
2.8 KiB
Markdown
42 lines
2.8 KiB
Markdown
|
## rwmutex
|
|||
|
|
|||
|
[sync.RWMutex](https://golang.org/pkg/sync/#RWMutex) -- это примитив синхронизации,
|
|||
|
предоставляющий доступ к критической секции произвольному количеству читателей,
|
|||
|
не более, чем одному читателю. При этом, если есть писатель, то читателей нет.
|
|||
|
|
|||
|
### Что нужно сделать?
|
|||
|
|
|||
|
Нужно написать реализацию 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`).
|
|||
|
С блокировкой на чтение связано число, число активных читателей.
|
|||
|
При взятии блокировки (`RLock`) это число инкрементируется.
|
|||
|
При завершении чтения (`RUnlock`) блокировка на чтение уменьшает счётчик.
|
|||
|
|
|||
|
#### Свойства
|
|||
|
1. Писатель не заблокируется при взятии блокировки только при условии,
|
|||
|
что никакой другой писатель и никакой другой читатель не владеет соответствующей блокировкой.
|
|||
|
2. Если какой-то писатель взял блокировку на запись, любой новый писатель или читатель заблокируется при взятии блокировки.
|
|||
|
3. Если какой-то читатель взял блокировку на чтение, любой новый писатель заблокируется на взятии блокировки.
|
|||
|
Однако любой писатель сможет взять блокировку на чтение.
|
|||
|
|
|||
|
Для выполнения этих свойств достаточно двух каналов.
|