为什么不推出我的goroutines?

Ran*_*ert 1 go goroutine

不,这不是因为我的程序结束太快了.

我有这个脚本:

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")
}
Run Code Online (Sandbox Code Playgroud)

在包含可执行文件的目录中,我有两个以开头的文件,abc_因此输出为:

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.
Run Code Online (Sandbox Code Playgroud)

脚本不会停止,它永远不会记录Now exiting,因为它在空的循环中循环.但我没有看到这个In goroutine for file消息.

为什么会这样?我究竟做错了什么?

谢谢您的帮助!

two*_*two 6

如果您的程序正在运行GOMAXPROCS=1(即单个OS线程),则for{}冻结它,而不会让Go的用户模式调度程序运行.这是关于它的问题.JimB指出它会导致其他问题GOMAXPROCS; 最终运行时必须停止goroutine进行垃圾收集,它无法停止for{}.

更改for{}select{}让调度程序运行并且不吃CPU.在这个简化的程序中,你的goroutine代码运行.它的结尾是"所有goroutines都睡着了 - 死锁!" 因为你的其他goroutine退出,唯一剩下的一个(主要)挂在了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")
}
Run Code Online (Sandbox Code Playgroud)

当然,你通常不想挂goroutine甚至select{}; 在你的程序结束之前,这将留下一些资源.要构建有用的东西,你需要其他东西,如a sync.WaitGroup或channel.