GO语言使用共享变量实现并发

本文探讨了GO语言中并发编程的关键概念,包括竞态条件、互斥锁sync.Mutex及其Unlock方法,以及读写互斥锁sync.RWMutex的应用。通过使用锁,可以确保在多goroutine环境下正确地访问共享变量,防止数据竞争。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1 竞态

    在串行程序中(即程序中只有一个goroutine),程序中各个步骤的执行顺序由程序逻辑来决定。
    竞态是指在多个 goroutine 按照某些交错顺序执行时程序无法给出正确的结果。竞态对于程序是致命的,因为它们可能潜伏在程序中,出现频率很低,不易重现。

1.2 互斥锁:sync.Mutex

    其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,(如果再次加锁,就会造成死锁问题)。直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁。

Unlock()用于解锁m,如果在使用Unlock()前未加锁,就会引起一个运行错误.已经锁定的Mutex并不与特定的goroutine相关联,这样可以利用一个goroutine对其加锁,再利用其他goroutine对其解锁。

import "sync"

var(
    mu sync.Mtuex
    balance int
)

func Deposit(amount int){
    mu.lock()
    balance += amount
    mu.unlock()
}

func Balance() int {
    mu.lock() 
    b := balance
    mu.unlock()
    return b
}

也可以使用同样的理念,使用一个容量为 1 缓冲通道来实现模拟一个互斥锁。

var(
    mu := make(chan struct{}, 1)
    balance int
)

func Depsit(amount int){
    mu<- struct{}{}   //获取令牌
    balance += amount
    <-mu              //释放令牌
}

func Balance() int {
    mu<- struct{}{}    //获取令牌
    b := amount
    <- mu              //释放令牌
    return b
}

1.3 读写互斥锁:sync.RWMutex

    RWMutex是一个读写锁,该锁可以加多个读锁或者一个写锁,其经常用于读次数远远多于写次数的场景.
    写锁,如果在添加写锁之前已经有其他的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的 Lock 调用会从获得的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定
    读锁,当有写锁时,无法加载读锁,当只有读锁或者没有锁时,可以加载读锁,读锁可以加载多个,所以适用于"读多写少"的场景
package main

import (
    "fmt"
    "sync"
    "time"
)

var global int

var mutex sync.RWMutex

func Reader() {

    mutex.RLock() //读锁
    fmt.Printf("读到的是%d\n", global)
    defer mutex.RUnlock() //释放读锁
}

func Write() {
    mutex.Lock()
    defer mutex.Unlock()
    global += 3
}

func main() {
    for x := 0; x < 100; x++ {
        go Reader()
    }
    for x := 0; x < 100; x++ {
        go Write()
    }
    for x := 0; x < 100; x++ {
        go Write()
    }
    time.Sleep(10 * time.Second)     //这里主 goroutine 要等待,不然副 goroutine 还没执行完,主 goroutine 退出,别的 goroutine 也就会退出
    fmt.Printf("最后变量是%d", global)          //最后输出的是 600 。

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值