欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

Go-条件变量的那些事

时间:2023-07-04

Wait(): 把当前的 goroutine 加入当前条件变量的通知队列.解锁当前条件变量基于的互斥锁、所以 wait 前必须加锁.当前 goroutine 阻塞在 wait()通知到来并唤醒了当前 goroutine 后 解锁当前条件变量基于的互斥锁执行后面的代码

Signal()Broadcast

上代码, 自己品:

package mainimport ("fmt""sync""time")type MailBox struct {count uint8locker sync.RWMutexsendCond *sync.CondrecvCond *sync.Cond}func (self *MailBox) Init() {self.sendCond = sync.NewCond(&self.locker)self.recvCond = sync.NewCond(self.locker.RLocker())}func (self *MailBox) Send() {self.locker.Lock()defer self.locker.Unlock()for self.count == 1 {fmt.Println("Send wait...")self.sendCond.Wait()}fmt.Println("Send")self.count = 1self.recvCond.Signal()}func (self *MailBox) Recv() {self.locker.RLock()defer self.locker.RUnlock()for self.count == 0 {fmt.Println("Recv wait...")self.recvCond.Wait()}fmt.Println("Recv")self.count = 0self.sendCond.Signal()}func main() {var mailBox MailBoxmailBox.Init()go func() {for i := 0; i < 5; i++ {mailBox.Send()}}()go func() {for i := 0; i < 5; i++ {mailBox.Recv()}}()time.Sleep(time.Second * 2)}

package mainimport ("fmt""sync""time")type MailBox struct {count uint8locker sync.RWMutexsendCond *sync.CondrecvCond *sync.Cond}func (self *MailBox) Init() {self.sendCond = sync.NewCond(&self.locker)self.recvCond = sync.NewCond(self.locker.RLocker())}func (self *MailBox) Send(i int) {fmt.Println(i)self.locker.Lock()fmt.Println(i, "lock")defer self.locker.Unlock()for self.count == 1 {fmt.Println(i, " Send wait...")self.sendCond.Wait()}fmt.Println(i, " Send")self.count = 1self.recvCond.Signal()}func (self *MailBox) Recv() {self.locker.RLock()defer self.locker.RUnlock()for self.count == 0 {fmt.Println("Recv wait...")self.recvCond.Wait()}fmt.Println("Recv")self.count = 0self.sendCond.Signal()}func main() {var mailBox MailBoxmailBox.Init()go func() {for i := 0; i < 5; i++ {mailBox.Send(i) // Send 里面的 for 循环会阻塞}}()time.Sleep(time.Second * 2)}

package mainimport ("fmt""sync""time")type MailBox struct {count uint8locker sync.RWMutexsendCond *sync.CondrecvCond *sync.Cond}func (self *MailBox) Init() {self.sendCond = sync.NewCond(&self.locker)self.recvCond = sync.NewCond(self.locker.RLocker())}func (self *MailBox) Send(i int) {fmt.Println(i)self.locker.Lock()fmt.Println(i, "lock")defer self.locker.Unlock()for self.count == 1 {fmt.Println(i, " Send wait...")self.sendCond.Wait()}fmt.Println(i, " Send")self.count = 1self.recvCond.Signal()}func (self *MailBox) Recv() {self.locker.RLock()defer self.locker.RUnlock()for self.count == 0 {fmt.Println("Recv wait...")self.recvCond.Wait()}fmt.Println("Recv")self.count = 0self.sendCond.Signal()}func main() {var mailBox MailBoxmailBox.Init()go func() {for i := 0; i < 5; i++ {go func(i int) {mailBox.Send(i) // wait 调用后, 其他的Send就可以获得锁了}(i)}}()time.Sleep(time.Second * 2)}

package mainimport ("fmt""sync""time")func main() {var locker sync.Mutexvar cond *sync.Cond = sync.NewCond(&locker)go func() {locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 1)fmt.Println("1: wait...")cond.Wait()}()go func() {//cond2 := cond // 可以在 cond 使用前拷贝cond2 := *cond // 可以在 cond 使用前拷贝locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 2)fmt.Println("2: wait...")cond2.Wait()}()time.Sleep(time.Second * 5)}

package mainimport ("fmt""sync""time")func main() {var locker sync.Mutexvar cond *sync.Cond = sync.NewCond(&locker)go func() {locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 1)fmt.Println("1: wait...")cond.Wait()}()go func() {locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 2)cond2 := cond // 在 cond 使用后拷贝指针的副本, 可以使用fmt.Println("2: wait...")cond2.Wait()}()time.Sleep(time.Second * 5)}

package mainimport ("fmt""sync""time")func main() {var locker sync.Mutexvar cond *sync.Cond = sync.NewCond(&locker)go func() {locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 1)fmt.Println("1: wait...")cond.Wait()}()go func() {locker.Lock()defer locker.Unlock()time.Sleep(time.Second * 2)cond2 := *cond // 在 cond 使用后拷贝值的副本, 不可以使用fmt.Println("2: wait...")cond2.Wait() // panic: sync.Cond is copied}()time.Sleep(time.Second * 5)}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。