为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
桃花长相依 2022-05-23 16:39:10
我正在尝试练习围棋套路。我在这里想念什么?这段代码给我返回了一个不同的数组结果。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)}
查看完整描述

1 回答

?
慕仙森

TA贡献1827条经验 获得超8个赞

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 的执行顺序,但你不会丢失数据,因为它是同步的。


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信