«

Golang 并发编程sync包

时间:2025-1-10 18:27     作者:杨佳乐     分类: Golang


package main

import (
    "fmt"
    "sync"
)

// sync包
func main(){

    // Go 语言的 sync 包提供了用于同步的原语,主要用于多个 goroutine 之间的协调与同步。
    // sync 包中有几个非常重要的同步工具,帮助你处理并发编程中的竞态条件、资源共享和执行顺序等问题

    // sync.WaitGroup
    // sync.WaitGroup 用于等待一组 goroutine 完成。它可以帮助你在多个 goroutine 执行完之后再继续执行后续的代码

    // 用法:
    // 调用 Add(n) 来设置等待的 goroutine 数量。
    // 每个 goroutine 执行完后,调用 Done() 来通知 WaitGroup,表示一个 goroutine 完成了。
    // Wait() 会阻塞,直到所有的 goroutine 都完成。

    //示例
    // func task(id int, wg *sync.WaitGroup) {
    //  defer wg.Done() // 标记 goroutine 完成
    //  fmt.Printf("任务 %d 开始\n", id)
    // }

    // func main() {
    //  var wg sync.WaitGroup

    //  // 启动多个 goroutine
    //  for i := 1; i <= 3; i++ {
    //      wg.Add(1) // 设置等待的 goroutine 数量
    //      go task(i, &wg)
    //  }

    //  wg.Wait() // 等待所有 goroutine 完成
    //  fmt.Println("所有任务完成")
    // }

    // sync.Mutex
    // 互斥锁,用于保护临界区,确保同一时刻只有一个 goroutine 可以访问共享资源。它可以防止多个 goroutine 同时访问共享数据,从而避免数据竞态问题
    // 用法:
    // Lock():获取锁,如果锁已经被其他 goroutine 持有,当前 goroutine 会被阻塞,直到锁被释放。
    // Unlock():释放锁,允许其他 goroutine 获取锁。

    // var (
    //  mu    sync.Mutex
    //  count int
    // )
    // func increment(wg *sync.WaitGroup) {
    //  defer wg.Done()
    //  mu.Lock()         // 获取锁
    //  count++           // 访问共享数据
    //  mu.Unlock()       // 释放锁
    // }

    // func main() {
    //  var wg sync.WaitGroup

    //  // 启动多个 goroutine 来并发地增加 count
    //  for i := 0; i < 5; i++ {
    //      wg.Add(1)
    //      go increment(&wg)
    //  }

    //  wg.Wait()
    //  fmt.Println("最终 count 值:", count)
    // }

    // sync.RWMutex
    // 读写锁,它允许多个 goroutine 同时读取共享数据,但写入操作会阻塞所有其他读写操作。适用于读多写少的场景
    // 用法:
    // RLock():获取读锁,多个 goroutine 可以同时获取读锁。
    // RUnlock():释放读锁。
    // Lock():获取写锁,写锁会阻塞所有的读锁和写锁。
    // Unlock():释放写锁。

    // var (
    //  rwmu   sync.RWMutex
    //  data   int
    // )

    // func readData(wg *sync.WaitGroup) {
    //  defer wg.Done()
    //  rwmu.RLock()       // 获取读锁
    //  fmt.Println("读取数据:", data)
    //  rwmu.RUnlock()     // 释放读锁
    // }

    // func writeData(wg *sync.WaitGroup, value int) {
    //  defer wg.Done()
    //  rwmu.Lock()        // 获取写锁
    //  data = value
    //  fmt.Println("写入数据:", data)
    //  rwmu.Unlock()      // 释放写锁
    // }

    // func main() {
    //  var wg sync.WaitGroup

    //  // 启动多个 goroutine
    //  wg.Add(3)
    //  go readData(&wg)
    //  go writeData(&wg, 42)
    //  go readData(&wg)

    //  wg.Wait()
    // }

    // sync.Once
    // 用于确保某个操作只执行一次,常用于初始化操作。无论多少次调用 Do(),该操作只会执行一次
    // 用法:
    // Do(f func()):执行传入的函数 f,如果该函数尚未执行过,它会执行一次。

    // var once sync.Once

    // func initOnce() {
    //  fmt.Println("初始化一次操作")
    // }

    // func main() {
    //  // 调用 Do,确保初始化操作只执行一次
    //  once.Do(initOnce)
    //  once.Do(initOnce) // 不会执行
    //  once.Do(initOnce) // 不会执行
    // }

    // sync/atomic 包
    // 提供了原子操作,用于在并发环境中安全地操作基本数据类型。原子操作是不可分割的操作,保证在执行过程中不会被其他 goroutine 中断
    // 常用函数:
    // atomic.AddInt32()
    // atomic.CompareAndSwapInt32()
    // atomic.LoadInt32()
    // atomic.StoreInt32()

    // import (
    //  "fmt"
    //  "sync"
    //  "sync/atomic"
    // )

    // var counter int32

    // func increment(wg *sync.WaitGroup) {
    //  defer wg.Done()
    //  atomic.AddInt32(&counter, 1) // 原子加操作
    // }

    // func main() {
    //  var wg sync.WaitGroup

    //  // 启动多个 goroutine
    //  for i := 0; i < 5; i++ {
    //      wg.Add(1)
    //      go increment(&wg)
    //  }

    //  wg.Wait()
    //  fmt.Println("最终计数:", counter)
    // }

    // 总结:
    // sync 包提供了强大的同步工具,帮助开发者处理并发编程中的数据共享、任务同步和并发安全问题。常用的同步工具有:
    // sync.WaitGroup:等待多个 goroutine 完成。
    // sync.Mutex:互斥锁,保证同一时刻只有一个 goroutine 访问共享资源。
    // sync.RWMutex:读写锁,支持多个 goroutine 同时读取,但写入时会阻塞所有读写操作。
    // sync.Once:确保某个操作只执行一次,适用于初始化操作。
    // sync/atomic:原子操作,保证在并发环境下的数据操作安全。
}

标签: Golang标准库