这是我参加「第五届青训营」伴学笔记创作活动的第2天。
前言
- 并发编程
- 依赖管理
- 测试
一、并发编程
参考教程:Go 并发 | 菜鸟教程 (runoob.com)
1. goroutine
Go语言支持并发,只需要使用Go关键字启动即可。
package main
import(
"fmt"
"time"
)
func say(s string){
for i:=0;i<2;i++{
time.Sleep(100*time.Millisecond)
fmt.Println(s)
}
}
func main(){
go say("1")
say("2")
}
则对应输出为
2
1
1
2
2.通道(channel)
- 通道(channel)是用来传递数据的一个数据结构。
- 通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。
- 操作符
<-用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
package main
import(
"fmt"
)
func sum(s []int,ch chan int){
sum:=0
for _,v:= range s{
sum+=v
}
ch<-sum //把sum输出到通道ch
}
func main(){
s:=[]int{7,2,8,-9,4,0}
ch:=make(chan int)
go sum(s[:len(s)/2],ch)
go sum(s[len(s)/2:],ch)
x,y := <-ch, <-ch //从通道ch中接收
fmt.Println(x,y,x+y)
}
则相应输出为:
-5 17 12
注意:这里使用的channel是无缓冲区的。 下面介绍带缓存的通道。
package main
import "fmt"
func main(){
//这里我们定义了一个可以存储整数类型的带缓冲通道
//缓冲区大小为2
ch:=make(chan int,2)
//因为ch是带缓冲的通道,我们可以同时发送两个数据
//而不用立刻需要去同步读取数据
ch<-1
ch<-2
//获取两个数据
fmt.Println(<-ch)
fmt.Println(<-ch)
}
则对应的输出为:
1
2
3. 互斥锁
Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。
Mutex:互斥锁。
RWMutex:单写多读模型。
package main
import (
"fmt"
"sync"
)
var (
// 逻辑中使用的某个变量
count int
// 与变量对应的使用互斥锁
countGuard sync.Mutex
)
func GetCount() int {
// 锁定
countGuard.Lock()
// 在函数退出时解除锁定
defer countGuard.Unlock()
return count
}
func SetCount(c int) {
countGuard.Lock()
count = c
countGuard.Unlock()
}
func main() {
// 可以进行并发安全的设置
SetCount(1)
// 可以进行并发安全的获取
fmt.Println(GetCount())
}
则对应输出为:
1
4.WaitGroup
- 在 sync.WaitGroup(等待组)类型中,每个 sync.WaitGroup 值在内部维护着一个计数,此计数的初始默认值为零。
- 等待组内部拥有一个计数器,计数器的值可以通过方法调用实现计数器的增加和减少。
- 当我们添加了 N 个并发任务进行工作时,就将等待组的计数器值增加 N。
- 每个任务完成时,这个值减 1。同时,在另外一个 goroutine 中等待这个等待组的计数器值为 0 时,表示所有任务已经完成。
package main
import (
"fmt"
"net/http"
"sync"
)
func main() {
var wg sync.WaitGroup // 声明一个等待组
var urls = []string{
"https://www.baidu.com/",
"https://www.163.com/",
"https://www.weibo.com/",
}
for _, url := range urls {
wg.Add(1) // 每个任务开始,等待组+1
go func(url string) {
defer wg.Done()
_, err := http.Get(url) // 执行访问
fmt.Println(url, err)
}(url)
}
wg.Wait() // 等待所有任务完成
fmt.Println("over")
}
二、依赖管理
参考:Go语言go mod包依赖管理工具使用详解 (biancheng.net)
go module 是Go语言从 1.11 版本之后官方推出的版本管理工具,并且从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具。
三、测试
参考:go test命令(Go语言测试命令)完全攻略 (biancheng.net)
Go语言拥有一套单元测试和性能测试系统,仅需要添加很少的代码就可以快速测试一段需求代码。
go test 命令,会自动读取源码目录下面名为 *_test.go 的文件,生成并运行测试用的可执行文件。