for 循环中的 Goroutines 返回不同的值

我正在尝试练习围棋套路。我在这里想念什么?这段代码给我返回了一个不同的数组结果。


func goRoutinesSearch(body string, keywords []string) {

     lowerBody := strings.ToLower(body)

     var matched []string

     var wg sync.WaitGroup

     wg.Add(len(keywords))

     for _, word := range keywords {

         go func(w string) {

             defer wg.Done()

             if strings.Contains(lowerBody, w) {

                 matched = append(matched, w)

             }

         }(word)

     }

     wg.Wait()

     fmt.Print(matched)

}


桃花长相依
浏览 103回答 1
1回答

慕仙森

matched = append(matched, w)是一个不同步的关键部分,导致竞争条件。这不是原子操作。goroutine 有许多不同的交错,会导致不同的输出,并且是完全不可预测的,可能会丢失数据。使这个线程安全(并发执行安全)的最简单方法是matched使用mutex同步访问:func goRoutinesSearch(body string, keywords []string) {     lowerBody := strings.ToLower(body)     var mutex = &sync.Mutex{}     var matched []string     var wg sync.WaitGroup     wg.Add(len(keywords))     for _, word := range keywords {         go func(w string) {             defer wg.Done()             if strings.Contains(lowerBody, w) {                 mutex.Lock()                 matched = append(matched, w)                 mutex.Unlock()             }         }(word)     }     wg.Wait()     fmt.Print(matched)}互斥锁确保在任何给定时间只有一个 go 例程能够执行append,matched因此您永远不会覆盖附加。我认为你可能仍然有不同的数组结果,具体取决于 goroutines 的执行顺序,但你不会丢失数据,因为它是同步的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go