一、Go语言进阶
-
并发:Go可以充分发挥多核优势,高效运行,多线程程序在多个核的cpu上运行。(Go语言就是为并发而生的)
-
协程Goroutine:
(1)栈KB级别,相较于线程更具有优势
(2)可以用于快速打印,样例:
func hello(i int) {
println("hello goroutine:" + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
} func main() {
HelloGoRoutine()
}
其中go是协程的关键,在函数调用前加关键字go
Sleep是阻塞,保证子协程执行完前主协程不退出
特点:并行会乱序输出
3.通道 Channel:
(1)分为无缓冲通道和有缓冲通道
(2)类似生产消费模型,样例:
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)
}
}
make(chan **) 是创建通道的关键
dest有缓冲是为了更好的模拟消费者,消费者速度可能会慢一些,防止影响生产者的速度
按照顺序输出,可以保证并发安全的
4.并发安全Lock
(1)不加锁可能会导致结果错误
(2)加锁:对临界区的控制保证并发安全,要避免对共享内存做非并发安全的操作
(3)样例:
func add(){
for i:=0;i<2000;i++{
lock.Lock()
x+=1
lock.Unlock()
}
}
func add2(){
for i:=0;i<2000;i++{
x+=1
}
}
5.WaitGrouop:
(1)Add(delta int):计数器+delta
(2)Done():计数器-1,计数器为0后就表示所有并发任务已经全部完成
(3)Wait():阻塞直到计数器为0
(4)样例:
func ManyGoWait() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(j int) {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}
6.理解与心得:
(1)并发是一种快捷有效的运行方式,可以减少内存缩短时间,但是在协程时一定要保证并发安全,可以用Lock帮助实现
(2)通过通信实现共享内存,可以善用Channel
(3)WaitGroup可以简化代码
(4)并发方式就是同时多条线路运行,一同为了同一个目实现,这种高并发操作在安全下是高效率的