douyou4819 2016-03-04 20:44
浏览 28
已采纳

为什么我的goroutines没有启动?

No, it's not because my program ends too fast.

I have this script:

package main

import ("log"; "io/ioutil"; "strings")

const BASE_FILE_NAME = "abc_"

func mygoroutine(file_name string) {
    log.Println("In goroutine for file", file_name)
}


func get_file_names() []string {
  file_names := make([]string, 0)
  files, _ := ioutil.ReadDir("./")
  for _, file := range files {
      if strings.HasPrefix(file.Name(), BASE_FILE_NAME) {
        file_names = append(file_names, file.Name())
      }
  }

  return file_names
}

func main()  {
    file_names := get_file_names()
    for _, file_name := range file_names {
        log.Println("Now lunching goroutine for file", file_name)
        go mygoroutine(file_name)
    }

    log.Println("Finished launching.")

    for {}

    log.Println("Now exiting")
}

In the directory that contains the executable, I have two files that start with abc_ so the output is this:

2016/03/04 20:35:14 Now lunching goroutine for file abc_fr
2016/03/04 20:35:14 Now lunching goroutine for file abc_hrty
2016/03/04 20:35:14 Finished launching.

The script doesn't stop, it never logs Now exiting , because it loops in the empty for. But I do not see the In goroutine for file message.

Why is this happening? What am I doing wrong?

Thanks for the help!

  • 写回答

1条回答 默认 最新

  • dongxi5505 2016-03-04 20:58
    关注

    If your program is running with GOMAXPROCS=1 (that is, a single OS thread), for{} freezes it without ever letting Go's user-mode scheduler run. This is the issue about it. JimB points out it causes other problems regardless of GOMAXPROCS; eventually the runtime has to stop your goroutine for garbage collection, and it can't stop for{}.

    Changing for{} to select{} lets the scheduler run and doesn't eat CPU. In this reduced program, your goroutine code runs. It ends with "all goroutines are asleep - deadlock!" because your other goroutine quits and the only remaining one (main) is hung in the select{}.

    package main
    
    import "log"
    
    const BASE_FILE_NAME = "abc_"
    
    func mygoroutine(file_name string) {
        log.Println("In goroutine for file", file_name)
    }
    
    func main() {
        go mygoroutine("foo")
        log.Println("Finished launching.")
        select {}
        log.Println("Now exiting")
    }
    

    Of course, you normally don't want to hang a goroutine even with select{}; that's going to leave some resources in use until your program ends. To build something useful you'll need something else like a sync.WaitGroup or channel.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c