1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
"fmt"
"golang.org/x/sync/errgroup"
)

func main() {

var midList []int64

for i := 0; i < 100000000; i++ {

midList = append(midList, int64(i))
}

var g errgroup.Group

i := 0
for _, v := range midList {
mid := v
g.Go(func() error {

var err error
errG := err
fmt.Println("mid为:", mid)
if errG != nil {
return errG
}
return nil

})
i++
}

//println("i 为:", i)

}

会报错 panic: too many concurrent operations on a single file or socket (max 1048575)

而将fmt.Println换作println,则不会有这个错误


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"golang.org/x/sync/errgroup"
)

func main() {

var midList []int64

for i := 0; i < 100000000; i++ {

midList = append(midList, int64(i))
}

var g errgroup.Group

i := 0
for _, v := range midList {
mid := v
g.Go(func() error {

var err error
errG := err
println("mid为:", mid)
if errG != nil {
return errG
}
return nil

})
i++
}

//println("i 为:", i)

}


控制协程(goroutine)的并发数量

使用go build -gcflags=-m 文件名.go,

对于fmt.Println,因为其入参是interface,所以会发生逃逸

1
2
3
4
5
6
7
8
# command-line-arguments
./文件名.go:26:15: inlining call to fmt.Println
./文件名.go:17:6: moved to heap: g
./文件名.go:22:8: func literal escapes to heap
./文件名.go:26:16: "mid为:" escapes to heap
./文件名.go:26:16: mid escapes to heap
./文件名.go:26:15: []interface {}{...} does not escape
<autogenerated>:1: .this does not escape

对于println,其入参是字符串,不会发生逃逸

1
2
3
4
# command-line-arguments
./文件名.go:21:8: can inline main.func1
./文件名.go:16:6: moved to heap: g
./文件名.go:21:8: func literal escapes to heap




golang变量逃逸分析小探