go 语言中提供了互斥体和读写锁这两种并发数据结构的实现:互斥体(sync.mutex):允许一次只能有一个线程执行临界区,确保共享数据被串行访问。读写锁(sync.rwmutex):允许多个线程并发读取共享数据,但一次只能有一个线程写入共享数据,提高读写效率。

Go 语言中并发数据结构的实现
并发数据结构在多线程应用程序中至关重要,它们可以确保多个线程可以安全高效地访问共享数据。Go 语言提供了丰富的并发数据结构,在本文中,我们将介绍如何实现两个常用的并发数据结构:互斥体和读写锁。
互斥体
互斥体是一种同步原语,它允许一次只能有一个线程执行某个临界区。在 Go 语言中,可以使用 sync.Mutex 类型来实现互斥体。
import (
"fmt"
"sync"
)
func main() {
var mu sync.Mutex
cnt := 0
// 创建一个 goroutine 来增加计数器
go func() {
mu.Lock()
defer mu.Unlock()
cnt++
fmt.Println("goroutine increased the counter to", cnt)
}()
// 主 goroutine 等待 goroutine 完成
mu.Lock()
fmt.Println("main goroutine accessed the counter", cnt)
mu.Unlock()
}在这个示例中,mu.Lock() 会阻塞主 goroutine 直到它获取互斥锁,然后 goroutine 才能执行临界区(增加计数器)。一旦 goroutine 完成,它将释放锁,允许主 goroutine 访问计数器。
立即学习“go语言免费学习笔记(深入)”;
读写锁
读写锁是一种更高级的同步原语,它允许多个线程并发读取共享数据,但一次只能有一个线程写入共享数据。在 Go 语言中,可以使用 sync.RWMutex 类型来实现读写锁。
import (
"fmt"
"sync"
)
func main() {
var rwlock sync.RWMutex
cnt := 0
// 创建两个 goroutine 来读取计数器
for i := 0; i < 2; i++ {
go func(i int) {
rwlock.RLock()
defer rwlock.RUnlock()
fmt.Println("goroutine", i, "read the counter", cnt)
}(i)
}
// 主 goroutine 等待读取器完成
for i := 0; i < 2; i++ {
rwlock.Lock()
defer rwlock.Unlock()
cnt += i
fmt.Println("main goroutine increased the counter to", cnt)
}
}在这个示例中,多个 goroutine 可以同时持有读锁来读取计数器,而主 goroutine 在写入计数器之前会阻塞(持有写锁)。这样可以确保多个读取器和一个写入器可以安全地访问共享数据。










