为什么我的 goroutines 没有启动?
Why aren't my goroutines launched?
不是,不是因为我的程序结束的太快了。
我有这个脚本:
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")
}
在包含可执行文件的目录中,我有两个以 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.
脚本不会停止,它从不记录 Now exiting
,因为它在空循环中循环。但是我没有看到 In goroutine for file
消息。
为什么会这样?我做错了什么?
感谢您的帮助!
如果您的程序是 运行 GOMAXPROCS=1
(即单个 OS 线程),for{}
会冻结它,而不会让 Go 的用户模式调度程序 运行。 This is the issue about it。 JimB 指出,不管 GOMAXPROCS
是什么,它都会导致其他问题;最终 运行time 必须停止你的 goroutine 进行垃圾收集,它不能停止 for{}
.
将 for{}
更改为 select{}
让调度器 运行 不吃 CPU。 In this reduced program, your goroutine code runs。它以 "all goroutines are asleep - deadlock!" 结尾,因为你的另一个 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")
}
当然,即使有select{}
,你通常也不想挂起goroutine;这将在您的程序结束之前保留一些资源。要构建有用的东西,您需要其他东西,例如 sync.WaitGroup
或频道。
不是,不是因为我的程序结束的太快了。
我有这个脚本:
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")
}
在包含可执行文件的目录中,我有两个以 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.
脚本不会停止,它从不记录 Now exiting
,因为它在空循环中循环。但是我没有看到 In goroutine for file
消息。
为什么会这样?我做错了什么?
感谢您的帮助!
如果您的程序是 运行 GOMAXPROCS=1
(即单个 OS 线程),for{}
会冻结它,而不会让 Go 的用户模式调度程序 运行。 This is the issue about it。 JimB 指出,不管 GOMAXPROCS
是什么,它都会导致其他问题;最终 运行time 必须停止你的 goroutine 进行垃圾收集,它不能停止 for{}
.
将 for{}
更改为 select{}
让调度器 运行 不吃 CPU。 In this reduced program, your goroutine code runs。它以 "all goroutines are asleep - deadlock!" 结尾,因为你的另一个 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")
}
当然,即使有select{}
,你通常也不想挂起goroutine;这将在您的程序结束之前保留一些资源。要构建有用的东西,您需要其他东西,例如 sync.WaitGroup
或频道。