作者:看那个码农
公众号:看那个码农
上期内容介绍了Go语言学习之处理错误|Go主题月
- 什么是处理错误
- 理解错误类型
- 创建错误
- 从函数中返回错误
本篇内容将继续带领大家走进Go语言的世界。
1.本文简介
Go语言学习之创建Goroutine
2.Goroutine的定义
在最简单的计算机程序中,操作是依次执行的,执行顺序与出现顺序相同。
那能否有一种机制,使用者分配足够多的任务,系统能自动帮助使用者把任务分配到CPU上面,让这些任务并发运作,这种机制在Go语言中称为Goroutine。
Goroutine的概念类似于线程,
Go语言程序会智能将Goroutine中的任务合理地分配给每个CPU进行执行。
2.Goroutine的创建
Go程序中使用go关键字为函数创建一个Goroutine,一个函数可以创建多个Goroutine,一个Goroutine必定对应一个函数。
创建格式:
go 函数名(参数列表)
举个例子如下:
func hello() {
fmt.Println("Hello Goroutine!")
}
func main() {
hello()
fmt.Println("main goroutine done!")
}
这个示例主函数main中hello函数和下面的语句是串行的,
执行的结果是打印完Hello Goroutine!后打印main goroutine done!。
接下来我们在调用hello函数前面加上关键字go,也就是启动一个goroutine去执行hello这个函数。
package main
import (
"fmt"
)
func hello() {
fmt.Println("Hello Goroutine!")
}
func main() {
go hello()
fmt.Println("main goroutine done!")
}
输出为:
这一次的执行结果只打印了main goroutine done!,并没有打印Hello Goroutine!。
这是为什么呢?
在程序启动时,Go程序就会为main()函数创建一个默认的goroutine。
当main()函数返回的时候该goroutine就结束了,所有在main()函数中启动的goroutine会一同结束。
所以我们要想办法让main函数等一等hello函数。
最简单的方式就是使用time.Sleep。
具体代码如下所示:
package main
import (
"fmt"
"time"
)
func hello() {
fmt.Println("Hello Goroutine!")
}
func main() {
go hello()
fmt.Println("main goroutine done!")
time.Sleep(time.Second)
}
输出为:
执行上面的代码会发现,
这一次先打印main goroutine done!,然后紧接着打印Hello Goroutine!。
为了理解更深刻,我们再来看看下面的案例。
package main
import (
"fmt"
"time"
)
func running(){
var times int
for{
times++
fmt.Println("tick",times)
time.Sleep(time.Second)
}
}
func main() {
//并发执行程序
go running()
//接受命令行输入,随后显示“输入出来了”
var input string
fmt.Scanln(&input)
fmt.Println("输入出来了!")
}
输出为:
代码执行后,命令行会不断输出tick,同时可以接受用户输入,两个环节同时进行。
直到按Enter键时,将输入的内容写入input变量中并返回,整个程序终止。即代码全部终止,running所在的支线任务也因此随着主线任务的终止而终止。
3.理解并发与并行
并发与并行的概念总是容易混淆,我们来二者的区别
并发:同一时间段内执行多个任务。
并行:同一时刻执行多个任务。
两个概念的本质区别是,任务是否同时进行。
例如:
吃饭时,电话来了,需要停止吃饭去接电话。电话接完回来继续吃饭,这个过程是并发执行的。
吃饭时,电话来了,边吃饭边接电话。这个过程是并行执行的。
每次使用关键字go都会产生一个新的goroutine。从表面上看,所有的goroutine好像是在同时运行,但是由于计算机通常只具有有限数量的处理单元。因此从技术上来说,这些goroutine并不是真的在同时运行。
Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据任务需求创建成千上万个goroutine并发工作。
但是goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成。
4.Goroutine的拓展
Go语言还提供channel在多个goroutine间进行通信。
goroutine和channel是 Go 语言秉承的 CSP(Communicating Sequential Process)并发模式的重要实现基础。
我们将在下一节中继续讲述channel。
如果你觉得这篇内容对你有帮助的话:
1、点赞支持下吧,让更多的人也能看到这篇内容
2、关注公众号:看那个码农,我们一起学习一起进步。