Go语言工程实践进阶-协程 | 青训营笔记

46 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

并发与并行

并发是指多线程程序在一个核的CPU上运行,在同一时间点,任务不会同时运行。

image.png

并行是指多线程程序在多个核的CPU上运行,在同一时间点,任务一定是同时运行。

image.png

goroutine(协程)

goroutine 是 Go语言中的轻量级线程实现,由 Go 运行时(runtime)管理。Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。

Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。

线程: 内核态,线程跑多个协程,栈MB级别。

协程: 用户态,轻量级线程,栈KB级别。

为一个普通函数创建 goroutine 的写法如下:

go 函数名( 参数列表 )

package main

import (
	"fmt"
	"time"
)

func hello(i int) {
	println("hello goroutine : " + fmt.Sprint(i))
}

func HelloGoRoutine() {
	for i := 0; i < 5; i++ {
		go func(j int) {
			hello(j)
		}(i)
	}
	time.Sleep(time.Second)
}

func main() {
	HelloGoRoutine()
}

image.png

CSP (Communicating Sequential Processes)

在go语言中,协程之间通过通信来实现共享内存。

image.png

通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。

创建通道

make(chan 元素类型, [缓冲大小])

  1. 无缓冲通道 make(chan int)
  2. 有缓冲通道 make(chan int, 2)

使用通道发送数据

通道发送数据的格式

通道的发送使用特殊的操作符<-,将数据通过通道发送的格式为: 通道变量 <- 值

通道变量:通过make创建好的通道实例。

值:可以是变量、常量、表达式或者函数返回值等。值的类型必须与ch通道的元素类型一致。

// 创建一个空接口通道
ch := make(chan interface{})
// 将0放入通道中
ch <- 0
// 将hello字符串放入通道中
ch <- "hello"

package main

func CalSquare() {
	src := make(chan int)
	dest := make(chan int, 3)
        // 生产
	go func() {
		defer close(src)
		for i := 0; i < 10; i++ {
			src <- i
		}
	}()
        // 消费
	go func() {
		defer close(dest)
		for i := range src {
			dest <- i * i
		}
	}()
	for i := range dest {
		println(i)
	}
}

func main() {
	CalSquare()
}