Girdonцитирует10 дней назад
package main

import (

"fmt"

"sync"

"sync/atomic"

)

type atomCounter struct {

val int64

}

Это структура для хранения требуемой атомарной переменной int64.

func (c *atomCounter) Value() int64 {

return atomic.LoadInt64(&c.val)

}

Это вспомогательная функция, которая возвращает текущее значение атомарной переменной int64, используя atomic.LoadInt64().

func main() {

X := 100

Y := 4

var waitGroup sync.WaitGroup

counter := atomCounter{}

for i := 0; i < X; i++ {

Мы создаем множество горутин, которые изменяют общую переменную. Как указывалось ранее, благодаря использованию пакета atomic для работы с общей переменной мы получаем простой способ избежать состояний гонки при изменении ее значения.

waitGroup.Add(1)

go func(no int) {

defer waitGroup.Done()

for i := 0; i < Y; i++ {

atomic.AddInt64(&counter.val, 1)

}

Функция atomic.AddInt64() безопасно изменяет значение поля val структу­ры counter.

}(i)

}

waitGroup.Wait()

fmt.Println(counter.Value())

}

При выполнении atomic.go в ходе проверки состояний гонки мы получаем такой вывод:

$ go run -race atomic.go

400

Таким образом, атомарная переменная изменяется несколькими горутинами без каких-либо проблем.

В следующем подразделе показано, как с помощью горутин совместно использовать память.
  • Войти или зарегистрироваться, чтобы комментировать