文章目录
Goroutine
概述
goroutine是Go语言并行设计的核心,有人称之为go程。 Goroutine从量级上看很像协程,它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。
一般情况下,一个普通计算机跑几十个线程就有点负载过大了,但是同样的机器却可以轻松地让成百上千个goroutine进行资源竞争。
创建Goroutine
- 只需在函数调⽤语句前添加 go 关键字,就可创建并发执⾏单元。开发⼈员无需了解任何执⾏细节,调度器会自动将其安排到合适的系统线程上执行。
go
package main
import (
"fmt"
"time"
"runtime"
)
fucn Test_Goroutine(){
i := 1;
for {
if(i == 10){
//退出协程
runtime.Goexit();
}
i++;
fmt.Println(i);
//休眠1s
time.Sleep(time.Second *1);
}
}
func main(){
//启动协程
go Test_Goroutine()
//go中的死循环
for{}
}
Goroutine特性
- **主goroutine退出后,其它的工作goroutine也会自动退出:**主协程退出后,其他协程会立即退出
- 开发中,我们需要将主协程设计为阻塞保证其他协程能够正常执行任务
Goexit函数
- goexit函数会立即终止当前goroutine的执行
- goexit会击穿,retuin 不会
- goexit和retuin的区别
- 都可以结束函数,但是goexit具有击穿特性
- retuin执行之后只能执行当前函数的defer
- goexit执行后能保证所有注册过defer都会被执行
- os.Exit 函数是终止主协程的,调用os.Exit函数会结束整个程序
go
func MyPrint(){
defer fmt.Println("8888")
for{
fmt.Println("1111")
time.Sleep(time.second *1)
}
}
fucn Test_Goroutine(){
defer fmt.Println("6666")
i := 1;
for {
if(i == 10){
//退出协程
runtime.Goexit(); //goexit退出后能输出所有注册过defer
//return return 退出后只能输出当前函数的defer
}
i++;
fmt.Println(i);
//休眠1s
time.Sleep(time.Second *1);
}
}
func main(){
//启动协程
go Test_Goroutine()
//go中的死循环
for{}
}
总结
- goroutine 是go并发的基础
- goroutine从轻量级看,它比线程更小
- 主goroutine退出后,其它的工作goroutine也会自动退出
- 函数调⽤语句前添加 go 关键字,就可以创建协程
- 主协程退出后,其他协程会立即退出