Go语言学习之创建Goroutine|Go主题月

320 阅读4分钟

作者:看那个码农

公众号:看那个码农

上期内容介绍了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!")
}

这个示例主函数mainhello函数和下面的语句是串行的, 执行的结果是打印完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!")
}

输出为:

image.png

这一次的执行结果只打印了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)
}

输出为:

image.png

执行上面的代码会发现,

这一次先打印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("输入出来了!")

}

输出为:

image.png

代码执行后,命令行会不断输出tick,同时可以接受用户输入,两个环节同时进行

直到按Enter键时,将输入的内容写入input变量中并返回,整个程序终止。即代码全部终止,running所在的支线任务也因此随着主线任务的终止而终止。

3.理解并发与并行

并发与并行的概念总是容易混淆,我们来二者的区别

并发:同一时间段内执行多个任务。

并行:同一时刻执行多个任务。

两个概念的本质区别是,任务是否同时进行

例如:

吃饭时,电话来了,需要停止吃饭去接电话。电话接完回来继续吃饭,这个过程是并发执行的

吃饭时,电话来了,边吃饭边接电话。这个过程是并行执行的

每次使用关键字go都会产生一个新的goroutine。从表面上看,所有的goroutine好像是在同时运行,但是由于计算机通常只具有有限数量的处理单元。因此从技术上来说,这些goroutine并不是真的在同时运行。

Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据任务需求创建成千上万个goroutine并发工作。

但是goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成

4.Goroutine的拓展

Go语言还提供channel在多个goroutine间进行通信

goroutinechannelGo 语言秉承的 CSP(Communicating Sequential Process)并发模式的重要实现基础。

我们将在下一节中继续讲述channel

如果你觉得这篇内容对你有帮助的话:

1、点赞支持下吧,让更多的人也能看到这篇内容

2、关注公众号:看那个码农,我们一起学习一起进步。