Go语言中的条件变量Cond

一、条件变量Cond的定义

  • Go语言里的条件变量,是一个结构体,它包括对应的方法和属性字段。
  • Cond实现了⼀个条件变量,⼀个线程集合地,供线程等待或者宣布某事件的发⽣
  • 每个Cond实例都有⼀个相关的锁(⼀般是*Mutex或 *RWMutex类型的值),它必须在改变条件时或者调⽤Wait⽅法时保持锁定。 Cond可以创建为其他结构体的字段, Cond在开始使⽤后不能被拷⻉。 条件变量:sync.Cond,多个goroutine等待或接受通知的集合地。
  • 原型
    type Cond struct {
        noCopy noCopy
        L Lock
        notify notifyList
        checker copyChecker
    }

二、Cond里的方法

  • func NewCond(l Locker) *Cond
    使⽤锁 I 创建一个 *Cond。 Cond条件变量,总是要和锁结合使用。
  • func (c *Cond) Broadcast()
    Broadcast唤醒所有等待c的线程。调⽤者在调⽤本⽅法时,建议(但并⾮必须)保持c.L的锁定。
  • func (c *Cond) Signal()
    Signal唤醒等待c的⼀个线程(如果存在)。调⽤者在调⽤本⽅法时,建议(但并⾮必须)保持c.L的锁定。 发送通知给⼀个⼈。
  • func (c *Cond) Wait()
    a) Wait⾃⾏解锁c.L并阻塞当前线程,在之后线程恢复执⾏时, Wait⽅法会在返回前锁定c.L。和其他系统不同, Wait除⾮被Broadcast或者Signal唤醒,不会主动返回。 ⼴播给所有⼈。
    b) 因为线程中Wait⽅法是第⼀个恢复执⾏的,⽽此时c.L未加锁。调⽤者不应假设Wait恢复时条件已满⾜,相反,调⽤者应在循环中等待。

    案例1. 条件变量的使用
//myCondDes.go

// myCondDes project main.go
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var mutex sync.Mutex
	cond := sync.Cond{L: &mutex}
	condition := false

	go func() {
		time.Sleep(1 * time.Second)
		cond.L.Lock()
		fmt.Println("子goroutine已经锁定...")
		fmt.Println("子goroutine更改条件数值,并发送通知...")
		condition = true //更改数值
		cond.Signal()    //发送通知:一个goroutine
		fmt.Println("子goroutine...继续...")
		time.Sleep(5 * time.Second)
		fmt.Println("子goroutine已经解锁!")
		cond.L.Unlock()
	}()

	cond.L.Lock()
	fmt.Println("main 已经锁定...")
	if !condition {
		fmt.Println("main 即将等待...")
		//1.wait尝试解锁
		//2.等待-->当前的goroutine进入阻塞状态,等待被唤醒: signal(), broadcast()
		//3.一旦被唤醒后,又被锁定
		cond.Wait()
		fmt.Println("main 被唤醒...")
	}

	fmt.Println("main 继续")
	fmt.Println("main 解锁...")
	cond.L.Unlock()

	time.Sleep(3 * time.Second)
}


    效果如下:

图(1) 条件变量的使用

猜你喜欢

转载自blog.csdn.net/sanqima/article/details/108920387