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

处理 goroutine 时的奇怪事情

处理 goroutine 时的奇怪事情

Go
慕运维8079593 2021-06-29 13:15:08
有两件奇怪的事情。我在切片中制作了 1000 个数字,但它只打印 246,为什么是 246?为什么不是 1000?如果我删除"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)}
查看完整描述

2 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

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

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


查看完整回答
反对 回复 2021-07-12
?
万千封印

TA贡献1891条经验 获得超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)

}


查看完整回答
反对 回复 2021-07-12
  • 2 回答
  • 0 关注
  • 211 浏览
慕课专栏
更多

添加回答

举报

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