如何将Golang中的协程调用改写成长尾?
- 内容介绍
- 文章标签
- 相关推荐
本文共计822个文字,预计阅读时间需要4分钟。
相关专题:
go 里没有“调协程”这个操作——goroutine 是启动的,不是“调用”的;它一旦启动就独立运行,不支持像函数那样被主动“调”或“唤起”。如果你在找的是“如何启动、控制、等待或通信协程”,那下面这些才是实际要做的。
怎么启动一个 goroutine
用 go 关键字前缀函数调用即可。它会立刻把函数作为新协程异步执行,当前 goroutine 不阻塞。
常见错误:误以为 go func(){}() 启动后能立即拿到返回值——不能,它没有返回值上下文。
-
go fmt.Println("hello")—— 启动即执行,无返回 -
go myFunc(x, y)—— 参数在go语句执行时求值(注意闭包变量捕获问题) - 如果需要传参且避免循环变量陷阱,显式传参:
for i := range items { go func(idx int) { ... }(i) }
怎么等 goroutine 结束(别用 sleep 硬等)
靠 time.Sleep 等是不可靠的,应使用同步机制。最常用的是 sync.WaitGroup。
典型场景:批量启动 goroutine 处理任务,主协程需等全部完成再继续。
立即学习“go语言免费学习笔记(深入)”;
- 先
wg.Add(n)声明要等几个 - 每个 goroutine 结尾调
wg.Done() - 主协程调
wg.Wait()阻塞直到全部 Done - 注意:
WaitGroup的Add必须在go语句之前或同时发生,否则可能 panic
goroutine 之间怎么传数据(别共享内存)
Go 推荐用 channel 通信,而不是通过全局变量或指针共享内存。channel 是类型安全、带同步语义的管道。
常见错误:往已关闭的 channel 发送数据会 panic;从已关闭且空的 channel 接收会得到零值 + false。
- 声明:
ch := make(chan int, 10)(10 是缓冲区大小,0 表示无缓冲) - 发送:
ch (无缓冲 channel 会阻塞直到有人接收) - 接收:
v, ok := (推荐带 ok 判断,尤其在循环中) - 关闭:
close(ch),仅发送方应调用,且只调一次
什么时候 goroutine 会泄漏(容易被忽略的点)
goroutine 泄漏不是语法错误,而是逻辑缺陷:协程启动了,但永远没机会结束,持续占用内存和栈空间。
最常见原因:channel 接收端没读、select 没 default、waitgroup 忘记 Done、或者死锁在 channel 发送/接收上。
- 用
runtime.NumGoroutine()在测试前后打点,辅助发现异常增长 - HTTP server 中启 goroutine 处理请求,但没设超时或 context 取消,容易积压
- 无限 for-select 循环中,所有 case 都阻塞且没
default,协程就卡死了
本文共计822个文字,预计阅读时间需要4分钟。
相关专题:
go 里没有“调协程”这个操作——goroutine 是启动的,不是“调用”的;它一旦启动就独立运行,不支持像函数那样被主动“调”或“唤起”。如果你在找的是“如何启动、控制、等待或通信协程”,那下面这些才是实际要做的。
怎么启动一个 goroutine
用 go 关键字前缀函数调用即可。它会立刻把函数作为新协程异步执行,当前 goroutine 不阻塞。
常见错误:误以为 go func(){}() 启动后能立即拿到返回值——不能,它没有返回值上下文。
-
go fmt.Println("hello")—— 启动即执行,无返回 -
go myFunc(x, y)—— 参数在go语句执行时求值(注意闭包变量捕获问题) - 如果需要传参且避免循环变量陷阱,显式传参:
for i := range items { go func(idx int) { ... }(i) }
怎么等 goroutine 结束(别用 sleep 硬等)
靠 time.Sleep 等是不可靠的,应使用同步机制。最常用的是 sync.WaitGroup。
典型场景:批量启动 goroutine 处理任务,主协程需等全部完成再继续。
立即学习“go语言免费学习笔记(深入)”;
- 先
wg.Add(n)声明要等几个 - 每个 goroutine 结尾调
wg.Done() - 主协程调
wg.Wait()阻塞直到全部 Done - 注意:
WaitGroup的Add必须在go语句之前或同时发生,否则可能 panic
goroutine 之间怎么传数据(别共享内存)
Go 推荐用 channel 通信,而不是通过全局变量或指针共享内存。channel 是类型安全、带同步语义的管道。
常见错误:往已关闭的 channel 发送数据会 panic;从已关闭且空的 channel 接收会得到零值 + false。
- 声明:
ch := make(chan int, 10)(10 是缓冲区大小,0 表示无缓冲) - 发送:
ch (无缓冲 channel 会阻塞直到有人接收) - 接收:
v, ok := (推荐带 ok 判断,尤其在循环中) - 关闭:
close(ch),仅发送方应调用,且只调一次
什么时候 goroutine 会泄漏(容易被忽略的点)
goroutine 泄漏不是语法错误,而是逻辑缺陷:协程启动了,但永远没机会结束,持续占用内存和栈空间。
最常见原因:channel 接收端没读、select 没 default、waitgroup 忘记 Done、或者死锁在 channel 发送/接收上。
- 用
runtime.NumGoroutine()在测试前后打点,辅助发现异常增长 - HTTP server 中启 goroutine 处理请求,但没设超时或 context 取消,容易积压
- 无限 for-select 循环中,所有 case 都阻塞且没
default,协程就卡死了

