Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Объекты синхронизации в Go

Объекты синхронизации в Go

Iskander (Alex) Sharipov

December 08, 2018
Tweet

More Decks by Iskander (Alex) Sharipov

Other Decks in Programming

Transcript

  1. Базовые объекты синхронизации Каналы, операторы select, for sync.Mutex, sync.RWMutex, sync.WaitGroup

    sync.Cond, sync.Once, sync.Map, sync.Pool atomic.Add*, atomic.CompareAndSwap*, atomic.Swap* atomic.Load*, atomic.Store*, atomic.Value 1. 2. 3. 4. 5. 2
  2. Каналы, оператор for ch := make(chan DataType, capacity) // создать

    close(ch) // закрыть ch <- struct{}{} // запись data <- ch // чтение for data := range ch { ... } // чтение через цикл 1. 2. 3. 4. 5
  3. Оператор select select { case ch <- 4: // была

    запись в канал case v := <-ch: // произошло чтение из канала default: // ничего из вышеперечисленного } 6
  4. Как исправить t1 := time.NewTicker(time.Second * 2) t2 := time.NewTicker(time.Second

    * 1) ... select { case <- t1.C: ... case <- t2.C: ... } t1.Stop(); t2.Stop() 8
  5. Ошибки в использовании select for { select { case <-

    ch: ... default: // без блокирующих операций 100% загрузка CPU } } 9
  6. Если канал закрыт close(ch) select { case v, success :=

    <- ch: // success == false } ch <- data // panic 1. 2. 3. 10
  7. Массив каналов chans := []chan int{make(chan int), make(chan int)} cases

    := make([]reflect.SelectCase, len(chans)) for i, ch := range chans { cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)} } chosen, value, ok := reflect.Select(cases) // ok == true если канал не закрыт 11
  8. sync.Mutex, sync.RWMutex var mu sync.Mutex // создать mutex mu.Lock() //

    заблокировать доступ к ресурсу mu.Unlock() // разблокировать доступ к ресурсу var mu sync.RWMutex // Как обычный mutex плюс mu.RLock() // блокировать ресурс на чтение mu.RUnlock() // разблокировать ресурс на чтение 1. 2. 12
  9. sync.WaitGroup Когда нужно дождаться выполнения всех горутин var wg sync.WaitGroup

    for _, task := range tasks { wg.Add(1) go func() { task.Do(); wg.Done() } } wg.Wait() 13
  10. sync.Once Выполнение кода один раз, ленивая загрузка var once sync.Once

    for i := 0; i < 10; i++ { go func() { // иницализация будет выполнена один раз once.Do(lazyInitialize) }() } 14
  11. sync.Cond c := sync.NewCond(&sync.Mutex{}) c.L.Lock() // вызов в горутинах, должен

    быть раньше чем в исто c.Wait() // ждем изменения, работаем со значением или c.Wait() c.L.Unlock() // --- c.L.Lock() // вызов источнике изменений c.Broadcast() // сигнал об изменении, c.Signal() - для одной г c.L.Unlock() 15
  12. sync.Pool Многократное повторное использование объектов bufPool := sync.Pool{ New: func()

    interface{} { return new(bytes.Buffer) } } // использование b := bufPool.Get().(*bytes.Buffer) b.Reset() // нужно сбросить состояние перед использованием bufPool.Put(b) // вернуть в pool 18
  13. atomic atomic.Add* // изменение значения atomic.CompareAndSwap* // поменять значения местами

    если отличаются atomic.Swap* // поменять значения местами atomic.Load* // прочитать значение atomic.Store* // записать значение atomic.Value // позволяет читать/писать занчение типа interface{} 1. 2. 3. 4. 5. 6. 20
  14. Ссылки Effective Go Go by Example Разбираемся с новым sync.Map

    в Go 1.9 Concurrency Patterns In Go GopherCon 2017: Kavya Joshi - Understanding Channels 1. 2. 3. 4. 5. 21