## 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. Если какой-то читатель взял блокировку на чтение, любой новый писатель заблокируется на взятии блокировки. Однако любой другой читатель сможет взять блокировку на чтение. Для выполнения этих свойств достаточно двух каналов. #### Активное ожидание Ваше решение не должно использовать активное ожидание. Активное ожидание (busy wait) это ситуация, когда заблокированная горутина проверяет условие в вечном цикле. Например: ```go func (wg *WaitGroup) Wait() { for { wg.lock <- struct{}{} if wg.ch1 == 0 { <-wg.lock return } <-wg.lock } } ```