Go并发编程-----死锁和活锁
作者:互联网
死锁和活锁
死锁:会使得所有并发程序在等待,如果没有外界干预,程序不能恢复
type values struct{
mu sync.Mutex
value int
}
func TestMutes(v1, v2 *values){
defer wg.Done()
v1.mu.Lock()
defer v1.mu.Unlock()
time.Sleep(2*time.Second)
v2.mu.Lock()
defer v2.mu.Unlock()
fmt.Println("v1+v2=:",v1.value+v2.value)
}
var wg sync.WaitGroup
func main(){
var a = values{
value:1,
mu:sync.Mutex{},
}
var b = values{
value: 2,
mu:sync.Mutex{},
}
wg.Add(2)
go TestMutes(&a,&b)
go TestMutes(&b,&a)
wg.Wait()
}
fatal error: all goroutines are asleep - deadlock!
由时间问题产生死锁,代码运行时机:
检测,防止和纠正死锁的四个方式:
- 相互排斥:并发进程同时拥有资源的独占权
- 等待条件:并发进程必须同时拥有一个资源,并等待额外的资源
- 没有抢占:并发进程拥有的资源只能被该进程释放
- 循环等待:一个并发进程p1必须等待一系列其他并发进程p2,p2也同时在等待p1
上面的代码中goroutine的资源无法做到(没有抢占)
活锁:正在主动执行并发操作的程序,但是这些操作不能向前推进程序的状态
//模拟人通过走廊
func main(){
cadence := sync.NewCond(&sync.Mutex{})
go func(){
for range time.Tick(1 *time.Millisecond){
cadence.Broadcast()
}
}()
takeStep := func(){
cadence.L.Lock()
cadence.Wait()
cadence.L.Unlock()
}
//tryDir允许一个人尝试一个方向移动
tryDir := func(dirName string, dir *int32, out *bytes.Buffer)bool{
fmt.Fprintf(out,"%v",dirName)
atomic.AddInt32(dir,1)//向一个方向移动
takeStep() //每个人每次移动的节奏一样
if atomic.LoadInt32(dir)==1{
fmt.Fprintf(out,".Success!")
return true
}
takeStep()
atomic.AddInt32(dir,-1)//表示不能走放弃
return false
}
var left, right int32
tryLeft := func(out *bytes.Buffer)bool{return tryDir(" left ",&left,out)}
tryRight := func(out *bytes.Buffer) bool{return tryDir(" right ",&right,out)}
walk := func(walking *sync.WaitGroup, name string){
var out bytes.Buffer
defer func() {fmt.Println(out.String())}()
defer walking.Done()
fmt.Fprintf(&out, "%v is trying to scoot:",name)
for i := 0; i < 5; i++{//对尝试次数进行限制
if tryLeft(&out) || tryRight(&out){//首先会尝试向左
return
}
}
fmt.Fprintf(&out,"\n%v hello!",name)
}
var peopleIn sync.WaitGroup//模拟两个人
peopleIn.Add(2)
go walk(&peopleIn,"tom")
go walk(&peopleIn,"alice")
peopleIn.Wait()
}
//结果:
//alice is trying to scoot: left right left right left right left right left right
alice hello!
tom is trying to scoot: left right left right left right left right left right
tom hello!
tom和alice在退出之前会持续竞争
标签:right,活锁,sync,mu,死锁,func,Go,out,left 来源: https://blog.csdn.net/alvin_666/article/details/90575032