Code前端首页关于Code前端联系我们

Golang 同步工具 方法及使用示例 Sync.Cond

terry 2年前 (2023-09-24) 阅读数 62 #后端开发

Golang同步工具Sync.Cond使用方法和示例

sync.Cond

sync.Cond 是一类基于 Golang 标准库提供的互斥/读写锁实现的条件变量,用于协调访问共同共享资源。多个goroutine。当共享资源的状态发生变化时,可以通知阻塞等待条件变化的goroutine。 sync.Cond提供了一个create方法和三个成员方法,如下:

  • NewCond(l Locker)。创建Cond对象,必须传入锁对象,互斥锁或者读写锁;
  • Wait() ,立即屏蔽goroutine并等待消息信号;
  • Signal(),发送信号通知,唤醒等待中的goroutine;
  • Broadcast(),发送信号消息,唤醒goroutine等待的人群。

sync.Cond 必须与互斥锁或读写锁一起使用,以确保共享资源不会被并发操作。当处于锁定状态时,程序将阻塞在Wait()方法中,直到另一个程序通过Broadcast()和Signal()方法发送通知信号。

方法及使用示例

特殊使用方法如下:

创建 Mutex 对象

var mutex = sync.Mutex{}

创建 Cond 对象,进入 Mutex

cond := sync.NewCond(&mutex)

现在等待 goroutine 的通知信号

cond.Wait()

发送通知信号,唤醒一个或多个正在等待的goroutine

cond.Signal() // 唤醒一个goroutine
// 或者 cond.Broadcast() 唤醒多个goroutine

看例子:

package main

import (
	"log"
	"sync"
	"time"
)

func read(index int, c *sync.Cond) {
	c.L.Lock()
	c.Wait()
	log.Println(index, "开始读")
	c.L.Unlock()
}

func write(c *sync.Cond) {
	log.Println("开始写")
	time.Sleep(time.Second)
	log.Println("唤醒其中一个goroutine")
	c.Signal()
}

func main() {
	cond := sync.NewCond(&sync.Mutex{})

	for i := 1; i <= 5; i++ {
		go func(index int) {
			read(index, cond)
		}(i)
	}

	write(cond)

	time.Sleep(time.Second * 3)
}

输出内容如下:

2023/05/19 22:01:34 开始写
2023/05/19 22:01:35 唤醒其中一个goroutine
2023/05/19 22:01:35 2 开始读

可以看出,Signal()方法只唤醒了一个或多个goroutine,而二十行可以改成c.Broadcast(),打开看效果,你会发现所有goroutine都被唤醒了。

总结

sync.Cond在基本机制的基础上开发了一个通知等待列表,当goroutine等待通知时将其添加到通知等待列表中,然后通过Signal()或Broadcast()发送通知信号)方法唤醒goroutine等待列表,实现与goroutine的通信和条件变量同步。

使用sync.Cond可以使并发程序更加高效和灵活,避免使用time.Sleep()或空for循环的一些弊端。不过,条件变量的使用也应该谨慎使用,避免出现死锁和竞争条件等问题。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门