猿问

处理 goroutine 时的奇怪事情

有两件奇怪的事情。

  1. 我在切片中制作了 1000 个数字,但它只打印 246,为什么是 246?为什么不是 1000?

  2. 如果我删除"log.Println("hey")"这一行,为什么只打印0?

我知道它可能有同步问题,但我之前没有写过任何并发程序,所以有什么文章可以推荐吗?

import (

      "log"

      "runtime"

)


func main() {


  count := 1000

  slice := make([] int,count)

  for i := 0; i <= count-1; i++ {

   slice[i] =i

  }

  for _,v := range slice{

    go echo(v)

  }

  log.Println("hey")//if delete this line,it just print 0

  runtime.Gosched()

}



func echo(v int) {

  log.Println(v)

}


慕运维8079593
浏览 212回答 2
2回答

慕斯709654

不能保证任何 go 例程在您的主例程完成之前运行。当主例程完成时,您的程序将退出,而无需等待您创建的所有 go 例程完成(甚至启动)。解决此问题的最简单方法是分配一个同步通道,将其传递给每个 echo 实例,并在您的日志语句之后向其写入一个令牌。然后主线程应该count在返回之前从该通道读取令牌。

万千封印

如果你退出你的主要 go 例程,它不会等待任何已经运行的 go 例程。您需要同步正在运行的 go 例程,根据我的经验,sync.WaitGroup是正确的通用解决方案。import (&nbsp; &nbsp; "log"&nbsp; &nbsp; "sync")func main() {&nbsp; &nbsp; count := 1000&nbsp; &nbsp; slice := make([]int, count)&nbsp; &nbsp; for i := 0; i <= count-1; i++ {&nbsp; &nbsp; &nbsp; &nbsp; slice[i] = i&nbsp; &nbsp; }&nbsp; &nbsp; wg := new(sync.WaitGroup)&nbsp; &nbsp; for _, v := range slice {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go echo(v, wg)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}func echo(v int, wg *sync.WaitGroup) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; log.Println(v)}
随时随地看视频慕课网APP

相关分类

Go
我要回答