WaitGroup не соблюдается дважды за - PullRequest
0 голосов
/ 07 мая 2020

Я использую разные примеры учебник У меня проблема с вложением двух циклов.

Что я хочу

сумма переменная должна дать 2500

Результат

sum = 2298, 2266, 2254

это как l oop doesn ' t дать вам время закончить

package main

import (
    "fmt"
    "sync"
    "time"
)

var iterate = 50
var sum = 0

func main() {

    timeStart := time.Now()

    var wg sync.WaitGroup

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

        for i2 := 0; i2 < iterate; i2++ {

            wg.Add(1)

            go func() {

                defer wg.Done()

                sum++

                time.Sleep(5 * time.Millisecond)

            }()

        }

    }

    wg.Wait()

    timeEnd := time.Now().Sub(timeStart)

    fmt.Println(timeEnd, sum)

}

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Как указано в комментариях. sum должен быть защищен sync.Mutex, блокировка перед изменением sum и разблокировка после. Измененный код, как показано ниже, распечатает 2500.

package main

import (
    "fmt"
    "sync"
    "time"
)

var iterate = 50
var sum = 0

func main() {


    m := sync.Mutex{}

    timeStart := time.Now()

    var wg sync.WaitGroup

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

        for i2 := 0; i2 < iterate; i2++ {

            wg.Add(1)

            go func() {

                defer wg.Done()

                m.Lock()
                sum++
                m.Unlock()

                time.Sleep(5 * time.Millisecond)

            }()

        }

    }

    wg.Wait()

    timeEnd := time.Now().Sub(timeStart)

    fmt.Println(timeEnd, sum)

}
0 голосов
/ 07 мая 2020

По-видимому, проблема заключается в записи в переменную одновременно из разных мест.

Для просмотра вывода ошибки

go run -race app.go
...