Go 语言入门-工程进阶
Note:只是个人学习记录,可能存在诸多错误,发现问题可以指出,共同学习交流,感谢!!!嘻嘻
Go 并发编程
并发与并行
1.多线程程序在一个核的cpu上运行
2.多线程序在多个核的cpu上运行
Go 语言的优势: 可以充分利用多核资源,高效运行
Go 并发的形式: Goroutine
1.协程: 用户态下运行,属于一种轻量级线程,栈是KB的级别
2.线程: 内核态下运行,线程运行多个协程,栈是MB级别
Go 开启协程的方式
func hello(i int) {
fmt.Println("Hello goroutine:"+ fmt.Sprint(i))
}
func HelloGoRotine() {
for i:= 0;i<5;i++{
go func(j int){
hello(j)
}(i)
}
}
go 启动一个协程是极为简单的,只需要在function前面加上go 关键字即可,这里涉及到关于go的一个匿名函数,如果在后面加上小括号是立即执行(有参数的话,传入相应的参数)
CSP(Communicating Sequential Processes)
go 一直提倡的是使用通信进行内存信息的共享而不是使用内存进行信息的共享
所以就涉及到一个go的类型chan
make(chan type,size) //方式 size 是可选的
ex:
make(chan int, 3)
make(chan int)
var ch chan <- int //只能进行写入
var ch <- chan int //只能进行读出
go 的chan还可以限制传输的方向(最后的两种方式
for example
func CalSquare(){
src := make(chan int)
dest := make(chan int, 3)
go func(){
defer close(src)
for i:= 0; i<10; i++ {
src <- i // 向chan 发送数据
}
}()
go func(){
defer close(dest) {
// 从chan 接收数据
for i := range src{
dest <- i*i
}
}
}()
// for 循环也可以从chan取出数据
for i := range dest{
print(i)
}
}
var (
x int64
lock sync.Mutex
)
// 为防止多个协程对同一个内存进行操作我们可以使用 sync.Mutex 上的Lock()和Unlock() 对操作进行包裹
func addWithLock(){
for i:=0;i<200;i++ {
lock.Lock()
x += 1
lock.Unlock()
}
}
func addWitheoutLock(){
for i:=0;i<200;i++{
x += 1
}
}
// 对比 加锁与不加锁
func Add(){
x = 0
for i:=0; i<5;i++ {
go addWithoutLock()
}
time.Sleep(time.Second)
println("WithoutLock:",x)
x = 0
for i:=0; i<5;i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock:",x)
}
除了Sync.Mutex 我们可以使用sync.WaitGroup
func ManyGoWait(){
var wg sync.WaitGroup
wg.Add(5)
for i:= 0; i<5; i++ {
go func(j int){
deger wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
Go 依赖管理
Go Module
go 项目使用 go Module进行管理
我们可以使用
go mod init xxx
初始化项目
依赖的第三方项目的相关文件会下载到GOPATH(可以使用环境变量进行指定特定的目录)下
1. bin 目录存放相应的二进制文件
2. pkg 目录存放编译生成的中间文件(目前也有源代码?
3. src 目录存放源代码
可以使用 go help get/mod 查看相关的命令与之相对应的操作