2

有两件奇怪的事情。

  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)
}
4

2 回答 2

3

不能保证任何 go 例程在您的主例程完成之前运行。当主例程完成时,您的程序将退出,而无需等待您创建的所有 go 例程完成(甚至开始)。

解决此问题的最简单方法是分配一个同步通道,将其传递给每个回显实例,并在您的日志语句之后向其写入一个令牌。然后主线程应该count在返回之前从该通道中读取令牌。

于 2013-11-22T07:08:44.740 回答
3

如果您退出主 go 例程,它不会等待任何已经运行的 go 例程。您需要同步正在运行的 go 例程,根据我的经验,sync.WaitGroup是正确的通用解决方案。

操场

import (
    "log"
    "sync"
)

func main() {

    count := 1000
    slice := make([]int, count)
    for i := 0; i <= count-1; i++ {
        slice[i] = i
    }
    wg := new(sync.WaitGroup)
    for _, v := range slice {
        wg.Add(1)
        go echo(v, wg)
    }
    wg.Wait()
}

func echo(v int, wg *sync.WaitGroup) {
    defer wg.Done()
    log.Println(v)
}
于 2013-11-22T09:00:11.880 回答