【go从入门到精通】精通并发编程-Go Mutex 互斥锁
package main
import (
"fmt"
"sync"
)
var (
// 定义全局变量counter
counter int
// 创建一个互斥锁
lock = &sync.Mutex{}
)
// increment函数用于递增counter的值
func increment() {
// 锁定互斥锁
lock.Lock()
// 注意:在解锁之前不要调用panic或者通过return返回
// 如果在解锁之前返回或者抛出panic,其他等待获取锁的goroutine会一直阻塞
defer lock.Unlock() // 使用defer语句在函数退出时自动解锁
counter++
}
func main() {
// 使用通道来控制并发的goroutine数量
var wg sync.WaitGroup
// 设置通道容量,限制并发数量
sem := make(chan struct{}, 2)
// 设置等待组的计数器为1000
wg.Add(1000)
for i := 0; i < 1000; i++ {
// 使用匿名函数来避免闭包中的变量i共享
go func() {
// 通过通道控制并发数
sem <- struct{}{}
increment()
// 完成一个goroutine的任务
wg.Done()
// 通过通道释放一个资源,允许另外的goroutine进入
<-sem
}()
}
// 等待所有goroutine完成
wg.Wait()
fmt.Println("Counter value:", counter)
}
这段代码使用了互斥锁来保证counter的递增操作是线程安全的。通过使用sync.WaitGroup
来等待所有的goroutine完成,并通过通道sem
来控制并发的goroutine数量,以此来避免过多的并发导致的资源问题。在increment
函数中,使用lock.Lock()
来锁定互斥锁,并使用defer lock.Unlock()
来确保在函数退出时解锁,这样做可以避免因为程序执行到一半发生panic或者提前返回而导致的数据不一致问题。
评论已关闭