```
func main() {
for i := 0; i < 4; i++ {
queryAll()
fmt.Printf("goroutines: %d\n", runtime.NumGoroutine())
}
}
func queryAll() int {
ch := make(chan int)
for i := 0; i < 3; i++ {
go func() { ch <- query() }()
}
return <-ch
}
func query() int {
n := rand.Intn(100)
time.Sleep(time.Duration(n) * time.Millisecond)
return n
}
```
```go
go func() { ch <- query() }()
```
这里你使用的无缓冲的 channel 会阻塞造成 goroutine 无法退出,可以修改 `ch` 的容量为 3,也可以添加超时控制。
另外使用 `rand.Intn()` 的时候要添加种子。
最后,使用 prrof 去找更方便:
```go
import (
"fmt"
"math/rand"
"net/http"
"time"
_ "net/http/pprof"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
func handler(rep http.ResponseWriter, req *http.Request) {
var a int
for i := 0; i < 4; i++ {
a += queryAll()
}
rep.Write([]byte(fmt.Sprintf("%d", a)))
}
...
...
```
这样请求 `http://127.0.0.1:8080/debug/pprof/goroutine?debug=1` 可以直观的看到 goroutine 在哪里泄漏的。
![image.png](https://static.studygolang.com/211230/9357f972bb3b247fc16befa293fb5974.png)
#1
更多评论
读取ch的放在循环里面,读取3次。
func queryAll() int {
count := 3
ch := make(chan int, count)
for i := 0; i < count; i++ {
go func() { ch <- query() }()
}
sum := 0
for i := 0; i < count; i++ {
sum += <-ch
}
return sum
}
#2