并发: 多线程程序在一个核的cpu上运行,通过时间片的分配来达到多线程的效果或者多线程程序在多个核的cpu上运行。
并行: 并行则就是广义上的并行
Go可以充分发挥多核优势,高效运行
线程: 是属于内核态的,直接通过cpu来控制,量级比较的重,线程中可以有多个协程 栈MB级
协程: 用户态的,轻量级线程,栈KB级
通过语句go来添加一个协程
协程之间的通信: 提倡通过通信共享内存而不是通过共享内存而实现通信
通过通信共享内存: 协程之间通过通道交互发送数据来达到共享通道这块资源
通过共享内存实现通信: 协程之间通过互斥的访问临界区资源获取信息来达到通信的效果。需要互斥的访问临界区资源导致了资源的利用率降低。 通道的类型
定义方式:make(chan 元素类型,[缓冲大小])
-
无缓冲通道 make(chan int)
-
有缓冲通道 make(chan int,2)
package main
import()
func main(){
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)
}
}
线程安全问题: 通过加锁来达到互斥访问实现线程的安全
package main
import (
"sync"
"time"
)
var(
x int64
lock sync.Mutex
)
func main(){
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)
}
func addWithLock() {
for i := 0; i < 2000; i++ {
lock.Lock()
x+=1
lock.Unlock()
}
}
func addWithoutLock() {
for i := 0; i < 2000; i++ {
x+=1
}
}
WaitGRoup:
WaitGroup 实现并发等待 WaitGroup 类实现的功能是:等待一系列协程并发地执行完毕。如果不等待所有协程执行完毕,可能会导致一些线程安全问题。sync.WaitGroup 包含 3 个方法:
| 作用 | 方法 |
|---|---|
| Add(delta int) | 主协程调用该方法,设置 delta 为需要等待的协程数量 |
| Done() | 每个子协程运行起来,当每个子协程执行结束后,调用 Done() 表示子协程运行结束 |
| Wait() | 当所有协程执行完毕后,代码块可使用 Wait() ,当 delta ==0时,才执行后续代码 例 |