Go语言应用--工程篇| 青训营笔记

48 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第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()  //这里可以附加一个预期期望值,是否符合预期
}