37 lines
2.1 KiB
Markdown
37 lines
2.1 KiB
Markdown
|
## cond
|
|||
|
|
|||
|
[sync.Cond](https://golang.org/pkg/sync/#Cond) — примитив синхронизации для эффективных межгорутинных нотификаций.
|
|||
|
|
|||
|
Обычно использование выглядит так: одни горутины ждут выполнения некоторого условия,
|
|||
|
а другие горутины выполняют это условие и информируют ждущих.
|
|||
|
|
|||
|
### Что нужно сделать?
|
|||
|
|
|||
|
Нужно написать реализацию Cond используя каналы.
|
|||
|
|
|||
|
Использование пакета [sync](https://golang.org/pkg/sync) в этой задаче запрещено!
|
|||
|
|
|||
|
```go
|
|||
|
type Cond struct {
|
|||
|
L Locker
|
|||
|
}
|
|||
|
|
|||
|
func New(l Locker) *Cond {}
|
|||
|
|
|||
|
func (c *Cond) Wait() {}
|
|||
|
func (c *Cond) Signal() {}
|
|||
|
func (c *Cond) Broadcast() {}
|
|||
|
```
|
|||
|
|
|||
|
`Locker` это [sync.Locker](https://golang.org/pkg/sync/#Locker), но мы не хотим использовать [sync](https://golang.org/pkg/sync).
|
|||
|
|
|||
|
У каждого `Cond` есть блокировка `L`, передающаяся в конструкторе.
|
|||
|
`Cond` поддерживает FIFO очередь ожидающих горутин.
|
|||
|
|
|||
|
* `Wait()` паникует, если `L` не взята.
|
|||
|
* `Wait()` добавляет текущую горутину в очередь, возвращает блокировку `L`, блокирует текущую горутину.
|
|||
|
Заснувшая горутина может быть разбужена другой горутиной через вызов `Signal()` или `Broadcast()`.
|
|||
|
При просыпании засыпавшая горутина продолжит исполнение, возьмёт `L` и завершит вызов `Wait()`.
|
|||
|
* `Signal()` извлекает и разблокирует первую блокировку из очереди, если такая есть, иначе no-op.
|
|||
|
* `Broadcast()` извлекает и разблокирует все блокировки из очереди. no-op, если очередь пустая.
|