Golang中那些未关闭的goroutine都去哪儿了?
Golang中那些未关闭的goroutine都去哪儿了? 我有点好奇Go语言是如何处理那些仍在运行但主goroutine已经终止的goroutine?比如下面的代码片段:
package main
import (
"fmt"
"time"
)
func main(){
message := make(chan string)
go func(){
<- message
time.Sleep(1*time.Second)
fmt.Println("working...")
}()
message <- "hello"
}
我确定goroutine中的打印永远不会执行,因为主goroutine在goroutine中的这些任务完成之前就终止了。Go语言是如何处理这些剩余任务的?
谢谢
更多关于Golang中那些未关闭的goroutine都去哪儿了?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
当 func main 终止时,整个进程也会随之终止,包括其中的所有 goroutine。
您可以通过使用等待组让 main 函数等待所有 goroutine 完成。
更多关于Golang中那些未关闭的goroutine都去哪儿了?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,当主goroutine(main函数)终止时,整个程序会立即退出,所有其他正在运行的goroutine都会被强制终止,无论它们处于什么状态。这是Go运行时的一个基本行为特性。
在你的代码示例中,确实如你所说,匿名goroutine中的fmt.Println("working...")永远不会执行。这是因为:
- 主goroutine向
message通道发送"hello"后立即结束 - 程序立即终止,不给匿名goroutine执行
time.Sleep和打印的机会
Go运行时不会为这些未完成的goroutine执行任何特殊的清理或资源回收 - 它们只是被强制停止。这可能导致一些问题:
- 打开的文件描述符可能不会正确关闭
- 数据库连接可能不会正常释放
- 内存中的临时数据可能丢失
示例代码演示:
package main
import (
"fmt"
"time"
)
func worker(id int) {
defer fmt.Printf("Worker %d: cleanup completed\n", id)
fmt.Printf("Worker %d: started\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Worker %d: work completed\n", id)
}
func main() {
for i := 1; i <= 3; i++ {
go worker(i)
}
// 主goroutine立即结束,不给worker goroutines完成的机会
fmt.Println("Main goroutine finished")
}
输出只会显示:
Main goroutine finished
可以看到,所有的defer语句和后续的打印都不会执行。
正确处理方式示例:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
defer fmt.Printf("Worker %d: cleanup completed\n", id)
fmt.Printf("Worker %d: started\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Worker %d: work completed\n", id)
}
func main() {
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait() // 等待所有worker完成
fmt.Println("All workers completed, main goroutine finished")
}
这个版本使用sync.WaitGroup确保所有goroutine完成工作后程序才退出。

