Go语言基础 | 青训营笔记 day2

40 阅读2分钟

这是我参与「第五届青训营 -后端场」笔记创作活动的的第2篇笔记。 下面是我的学习总结:

1.并发与并行

  • 并发:可以理解为去买东西,有两列队,但是只有一个售卖窗口。
  • 并行:就相当去买东西,有两列队,也有两个售卖窗口,一个窗口前一列队。

go天生支持并发,在go中内置实现了任务的调度和管理。并发由协程(goroutine)实现,类似于线程。创建goroutine只需要在函数前加一个go关键字,当我们需要并发时,只需要把任务写到函数中,然后使用go关键字开启一个goroutine去执行即可。

一般情况下,go语言是串行执行。这时,程序只有一个goroutine即mian函数。

package main

import "fmt"

func main() {
   seeHello()
   fmt.Println("hello main")
}

func seeHello() {
   fmt.Println("hello func")
}

19e2a60f47a1caf31b608a5fcad7ae5.png

然后,我们给main函数中的seeHello()函数前面加一个go关键字,即给seeHello()函数开一个goroutine。

package main

import "fmt"

func main() {
   go seeHello()
   fmt.Println("hello main")
}

func seeHello() {
   fmt.Println("hello func")
}

image.png

这时我发现输出的只有hello main,没有输出hello func。因为当给seeHello()函数单独开一个goroutine时,程序不再是串行执行,seeHello()函数与main函数不是同一个线程,seeHello()函数还没来得及执行,main函数就执行结束了。我们可以添加time.Sleep()让main函数浅睡一会,等一下seeHello()函数。

package main

import (
   "fmt"
   "time"
)

func main() {
   go seeHello()
   fmt.Println("hello main")
   time.Sleep(time.Second)
}

func seeHello() {
   fmt.Println("hello func")
}

image.png

而当有多个goroutine时,我们再让main函数sleep,就可能会出现不知道什么时候结束的情况。这时我们就需要使用sync.WaitGroup来解决这个问题。

package main

import (
   "fmt"
   "sync"
)

func main() {
   HelloGoroutine()
}

func HelloGoroutine() {
   var wg sync.WaitGroup
   wg.Add(5)
   for i := 0; i < 5; i++ {
      go func(j int) {
         defer wg.Done()
         fmt.Println("hello goroutine:", fmt.Sprint(j))
      }(i)
   }
   wg.Wait()
}

image.png

以上就是我今天的学习收获。