[ 并发编程与依赖管理 | 青训营笔记]

51 阅读2分钟

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

本堂课重点内容

  1. 并发编程
  • 协程Goroutine
  • 通道Channel
  • 锁Lock 
  • 线程同步WaitGroup
  1. 依赖管理
  • Gopath
  • Go Vendor
  • Go Module
  1. 单元测试(略)
  • 单元测试概念和规则
  • Mock测试
  • 基准测试

详细知识点介绍

并发编程

go语言运行时可以创建上万个协程,因此go语言开发适合高并发场景。

相关概念

  • 线程:内核态,CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位,一个进程可以由多个称为线程的执行单元组成,多线程比多进程之间更容易共享数据,在上下文切换中线程一般比进程更高效
  • 协程:用户态下的线程,goroutine的调度开销远远小于线程调度开销,用户可以自行控制协程的创建于销毁,极大程度避免了系统级线程上下文切换造成的资源浪费
  • 进程:进程是操作系统对一个正在运行的程序的一种抽象,进程是资源分配的最小单位
  • CSP:go提倡通过通信共享内存方式(CSP)
  • Channel:make(chan int, [cacheSize])有size参数的为有缓存通道,无参数为无缓存通道

依赖管理

依赖管理三要素

  • go.mod 配置文件,依赖描述
  • Proxy中心管理依赖库
  • 本地文件 go get/mod

单元测试

实践练习例子

  1. 协程输出
package main

import "time"

func hello(i int) {
	println("hello goroutine: ", i)
}

func main() {
	println("hello test")
	count := 5
	for i := 0; i < count; i++ {
		go func(j int) { // 在函数内调用函数时,在func关键字前加go关键字即可
			hello(j)
		}(i)
	}
	time.Sleep(time.Second)
}

  1. 并发锁
package main

import (
	"sync"
	"time"
)

var (
	x    int64 // 全局变量
	lock sync.Mutex
)

func addWithLock() {
	for i := 0; i < 2000; i++ {
		lock.Lock() // 开启锁
		x += 1
		lock.Unlock() // 释放锁
	}
}

func Add() {
	x = 0
	for i := 0; i < 5; i++ {
		go addWithLock()
	}
	time.Sleep(time.Second)
	println("result: ", x)
}

func main() {
	Add()
}

result: 10000

  1. 生产消费模型
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()
}

课后个人总结

本节课主要学习了并发编程的基本概念与依赖管理,由于时间关系,主要是根据视频课程,结合网上搜索到的一些资源进行学习。

引用参考

  1. juejin.cn/post/718822…
  2. blog.csdn.net/ma259516234…
  3. t.csdn.cn/cgx83