sync.Mutex

sync.Mutex

sync.Mutex是Go语言中的互斥锁,它用于在多个goroutine之间提供对共享资源的互斥访问,以确保同一时间只有一个goroutine可以访问共享资源。

sync.Mutex类型的定义如下:

type Mutex struct {
    state int32
    sema  uint32
}

sync.Mutex结构体中包含了两个字段:

  • state字段是一个int32类型的标志,用于表示锁的状态。0表示未锁定,1表示已锁定。
  • sema字段是一个uint32类型的信号量,用于控制goroutine的调度和阻塞。

sync.Mutex提供了两个方法:

  • Lock:获取互斥锁。如果锁已经被其他goroutine获取,当前goroutine将被阻塞,直到锁被释放。
  • Unlock:释放互斥锁。如果当前goroutine未持有锁,调用Unlock将会导致运行时错误。

下面是一个使用sync.Mutex的示例:

package main

import (
    "fmt"
    "sync"
)

func main() {
    var mutex sync.Mutex

    counter := 0

    wg := sync.WaitGroup{}
    wg.Add(10)

    for i := 0; i < 10; i++ {
        go func() {
            defer wg.Done()

            mutex.Lock()
            counter++
            fmt.Println("Counter:", counter)
            mutex.Unlock()
        }()
    }

    wg.Wait()
    fmt.Println("Program finished.")
}

在上面的示例中,我们创建了一个sync.Mutex实例mutex,然后启动了10个goroutine。每个goroutine首先调用mutex.Lock()获取互斥锁,然后对共享的counter变量进行加1操作,并打印出counter的值,最后调用mutex.Unlock()释放互斥锁。

运行示例会输出以下内容:

Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
Counter: 6
Counter: 7
Counter: 8
Counter: 9
Counter: 10
Program finished.

从输出可以看出,虽然有10个goroutine同时对counter变量进行加1操作,但由于使用了互斥锁,每次只有一个goroutine能够获取到锁并修改counter的值,从而保证了数据的一致性。

如果没有使用sync.Mutex,就难于保证数据的一致性

package main

import (
    "fmt"
    "sync"
)

func main() {
    var mutex sync.Mutex

    counter := 0

    wg := sync.WaitGroup{}
    wg.Add(10)

    for i := 0; i < 10; i++ {
        go func() {
            defer wg.Done()

            // mutex.Lock()
            counter++
            fmt.Println("Counter:", counter)
            // mutex.Unlock()
        }()
    }

    wg.Wait()
    fmt.Println("Program finished.")
}

Counter: 1
Counter: 3
Counter: 4
Counter: 5
Counter: 6
Counter: 7
Counter: 8
Counter: 9
Counter: 10
Counter: 2
Program finished.

需要注意的是,在使用sync.Mutex时,我们必须遵循以下规则:

  • 在每个对共享资源的修改操作之前,必须调用Lock方法获取锁。
  • 在对共享资源的修改操作完成后,必须调用Unlock方法释放锁。
  • 在持有锁期间,应尽量避免长时间的阻塞或耗时操作,以免影响其他goroutine的执行。
  • 不应该对已经持有的锁再次调用Lock方法,这将导致死锁。
  • 一般情况下,应尽量将锁的作用范围限制在最小的代码块中,以减少竞争和锁的持有时间。

使用互斥锁时,需要谨慎处理竞争条件和死锁问题,确保正确地获取和释放锁,以避免数据的不一致性和程序的死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值