Go 语言 多 goroutine 间的同步与通信技巧

Go阿木 发布于 2025-06-22 9 次阅读


摘要:Go 语言以其并发编程的高效和简洁著称。在多 goroutine 环境下,同步与通信是确保程序正确性和效率的关键。本文将深入探讨 Go 语言中多 goroutine 间的同步与通信技巧,包括通道(Channels)、互斥锁(Mutexes)、条件变量(Condition Variables)等,并通过实际代码示例进行说明。

一、

Go 语言内置的 goroutine 和 channel 提供了一种轻量级的并发机制,使得开发者可以轻松实现多线程任务。在多 goroutine 环境中,如何有效地同步和通信成为了一个挑战。本文将详细介绍 Go 语言中常用的同步与通信技巧。

二、通道(Channels)

通道是 Go 语言中用于 goroutine 间通信的主要方式。通道可以看作是一种特殊的类型,它允许一个 goroutine 发送数据到另一个 goroutine。

1. 创建通道

go

ch := make(chan int)


2. 发送数据

go

ch <- 1


3. 接收数据

go

data := <-ch


4. 关闭通道

go

close(ch)


示例代码:

go

func main() {


ch := make(chan int)


go func() {


for i := 0; i < 5; i++ {


ch <- i


}


close(ch)


}()

for data := range ch {


println(data)


}


}


三、互斥锁(Mutexes)

互斥锁用于保护共享资源,确保同一时间只有一个 goroutine 可以访问该资源。

1. 创建互斥锁

go

var mutex sync.Mutex


2. 加锁和解锁

go

mutex.Lock()


// 临界区代码


mutex.Unlock()


示例代码:

go

func main() {


var mutex sync.Mutex


var counter int

for i := 0; i < 1000; i++ {


go func() {


mutex.Lock()


counter++


mutex.Unlock()


}()


}

println(counter)


}


四、条件变量(Condition Variables)

条件变量用于在特定条件下阻塞和唤醒 goroutine。

1. 创建条件变量

go

var cond = sync.Cond{L: &mutex}


2. 等待条件

go

cond.L.Lock()


cond.Wait()


cond.L.Unlock()


3. 通知条件

go

cond.L.Lock()


cond.Broadcast() // 或 cond.Signal()


cond.L.Unlock()


示例代码:

go

func main() {


var cond = sync.Cond{L: &mutex}


var counter int

go func() {


for i := 0; i < 5; i++ {


cond.L.Lock()


cond.Wait()


counter++


cond.L.Unlock()


}


}()

for i := 0; i < 5; i++ {


cond.L.Lock()


cond.Broadcast()


cond.L.Unlock()


println(counter)


}


}


五、总结

本文详细介绍了 Go 语言中多 goroutine 间的同步与通信技巧,包括通道、互斥锁和条件变量。通过实际代码示例,读者可以更好地理解这些技巧的应用。在实际开发中,合理运用这些技巧可以有效地提高程序的并发性能和正确性。

注意:以上代码示例仅供参考,实际应用中可能需要根据具体情况进行调整。