Goroutine
# Goroutine
# 创建goroutine
只需在函数调⽤语句前添加 go 关键字,就可创建并发执⾏单元。开发⼈员无需了解任何执⾏细节,调度器会自动将其安排到合适的系统线程上执行。
在并发编程中,我们通常想将一个过程切分成几块,然后让每个goroutine各自负责一块工作,当一个程序启动时,主函数在一个单独的goroutine中运行,我们叫它main goroutine。新的goroutine会用go语句来创建。而go语言的并发设计,让我们很轻松就可以达成这一目的。
package main
import (
"fmt"
"time"
)
func newTask() {
i := 0
for {
i++
fmt.Printf("new goroutine: i = %d\n", i)
time.Sleep(time.Second)
}
}
func main() {
go newTask()
i := 0
for {
i++
fmt.Printf("main goroutine: i = %d\n", i)
time.Sleep(time.Second)
}
}
/**
main goroutine: i = 1
new goroutine: i = 1
new goroutine: i = 2
main goroutine: i = 2
main goroutine: i = 3
new goroutine: i = 3
new goroutine: i = 4
main goroutine: i = 4
main goroutine: i = 5
new goroutine: i = 5
......
*/
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
39
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
39
需要注意的是,如果main函数即主goroutine执行结束,那么go关键字启动的子goroutine也会直接结束
# 匿名创建
这里的创建方式和创建匿名函数是一致的,在函数前加上go关键字即可
package main
import (
"fmt"
"time"
)
func main() {
go func() {
i := 0
for {
i++
fmt.Printf("anonymous function goroutine: i = %d\n", i)
time.Sleep(time.Second)
}
}()
go func(a int, b int) bool {
fmt.Printf("a = %d , b = %d\n", a, b)
return a > b
}(100, 200)
//死循环一下
for {
time.Sleep(time.Second)
}
}
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
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
# Goexit函数和return
调用 runtime.Goexit() 将立即终止当前 goroutine 执⾏,调度器确保所有已注册 defer 延迟调用被执行。
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
defer fmt.Println("A.defer")
func() {
defer fmt.Println("B.defer")
// return //这里return只会结束当前函数,即后面的不会执行,但是外部函数不受影响
runtime.Goexit() // 终止当前 goroutine, import "runtime"
fmt.Println("B") // 不会执行
}()
fmt.Println("A") // 不会执行
}() //不要忘记()
//死循环,目的不让主goroutine结束
for {
}
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
运行结果为:
B.defer
A.defer
所以,使用return仅仅是终止调用
return
的function
,而使用runtime.Goexit()
则是退出整个goroutine
# Channel
在 GitHub 上编辑此页 (opens new window)
最后更新: 2023/05/05, 20:05:00