这是我参与「第五届青训营 」伴学笔记创作活动的第2天
线程与协程
协程主要位于用户态,轻量级线程、栈MB级别 线程位于内核态,线程内具备多个协程 协程的开销远远小于线程的开销 协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
go func() {}//定义生成协程
Channel通道
并发,并行同步 GO最大限度的运用多核并发效率。 协程间通信:通道和临界区 临界区需要申请临界区资源需要加锁等 并发安全 WaitGroup计数器 确保数据同步
package concurrence
import (
"fmt"
"sync"
)
func hello(i int) {
println("hello world : " + fmt.Sprint(i))
}
func ManyGo() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)//计数器+1
go func(j int) {//创建一个协程
defer wg.Done()//计数器-1
hello(j)
}(i)
}
wg.Wait//直到主线程阻塞直到计数器为0才执行
}
package concurrence
func CalSquare() {
src := make(chan int) //无缓冲通道
dest := make(chan int, 3)//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)
}
}
单元测试
覆盖面越大越大,其中单元测试的覆盖面最广,成本最低 常使用_test.go来命名测试文件。
func AppendInt() {
intArray := [3]int64{1, 2, 3}//初始化函数
func(arr [3]int64) { //创建函数
arr[2] = 4
fmt.Println("inner func array:",arr)
}(intArray)
fmt.Println("outer func array:",intArray)
}
package attention
import "testing"
func TestAppendInt(t *testing.T) {//编写测试函数,调用功能函数
AppendInt() //这里可以附加一个预期期望值,是否符合预期
}