Go语言入门-工程实践 | 青训营笔记

31 阅读2分钟

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

并发vs并行

  • 并发:多线程在一个核上运行,一条路上多个时间有不同的车辆汇入

  • 并行:多修一条路,每条路上有一辆车在跑,成本大得多

Goroutine(线程vs协程)

  • 协程:用户态,轻量级,栈MB级别
  • 线程:内核态,线程跑多个协程,栈MB级别 图文解释:

image.png 举例:

image (1).png

  • go func()就是多协程的使用方法,一次可以创建上万级别
  • Sleep函数用来等待协程运行完毕

CSP(通讯共享内存)

  • go语言提倡通过通讯共享内存而不是通过共享内存来实现通讯

Channel(通道)

  • 创建:通过make(chan 元素类型,[缓冲大小])
  • 分为两个类型:1.无缓冲通道 make(chan int)不指定大小 2.有缓冲通道 make(chan int,2)指定大小
package main

import (
	"fmt"
)

func  main() {
	src := make(chan int)
	dest := make(chan int, 3)
	// 子协程src发送0~9数字
	go func() {
		defer close(src) // 推迟关闭,当子协程src结束的时候再关闭,减少资源浪费
		for i := 0; i < 10; i++ {
			src <- i//相当于将i发送给通道src
		}
	}()
	// 子协程dest计算输入数字的平方
	go func() {
		defer close(dest)//与之前一样,推迟关闭
        // 通过 range 关键字来实现遍历读取到的数据
		for i := range src {
			dest <- (i * i)//将i的平方发送给dest通道
		}
	}()
	// 主协程输出最后的答案
	// 这里可以暂时认为子协程需要使用匿名函数
	for i := range dest {
        // 因为主协程可能会有更多的复杂操作,比较耗时,所以用带缓冲的通道可以避免问题
		fmt.Println(i)
	}
}


并发安全Lock

image (2).png

  • 主要是
lock.Lock()
x+=1
lock.Unlock()

部分可以通过lock锁的方式来实现并发安全

WaitGroup

image (3).png

  • Add(n)计数器+n
  • Done()计数器-1
  • Wait()阻塞到计数器为0
  • 通过上述操作来代替sleep操作,让并发操作更加安全