Go语言并发编程中Mutex有几种状态

发布于 1周前 作者 zlyuanteng 最后一次编辑是 5天前 来自 问答

Go语言并发编程中Mutex有几种状态

mutexLocked — 表示互斥锁的锁定状态; mutexWoken — 表示从正常模式被从唤醒; mutexStarving — 当前的互斥锁进入饥饿状态; waitersCount — 当前互斥锁上等待的 Goroutine 个数;

1 回复

在Go语言的并发编程中,sync.Mutex 是用来保护共享资源不被多个goroutine同时访问的重要工具。虽然 sync.Mutex 的内部实现细节对外部是隐藏的,以提供简洁和安全的抽象,但从功能的角度,我们可以将其状态大致分为以下几种:

  1. 解锁(Unlocked):这是 sync.Mutex 的默认状态,表示没有任何goroutine持有该互斥锁,任何尝试加锁的goroutine都可以成功获取锁并进入临界区。

  2. 锁定(Locked):当某个goroutine成功调用 Lock() 方法后,sync.Mutex 进入锁定状态,表示当前有且仅有一个goroutine持有该锁,其他尝试加锁的goroutine将会被阻塞,直到锁被释放。

  3. 饥饿(理论上不存在显式状态,但属于行为特性):虽然 sync.Mutex 没有直接的“饥饿”状态,但长时间的锁争用可能导致某些goroutine长时间等待而无法获取锁,这种情况被称为“饥饿”。Go 1.9 版本之后,sync.Mutex 实现了自旋锁(spinlock)来减少锁的延迟,并可能包含公平性机制(如Go 1.18中引入的公平锁尝试),以减少饥饿情况的发生。

示例代码

下面是一个简单的示例,展示如何在Go中使用 sync.Mutex 来保护共享资源:

package main

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

var (
	counter int
	mu      sync.Mutex
)

func increment(wg *sync.WaitGroup) {
	defer wg.Done()
	mu.Lock()
	counter++
	fmt.Println("Counter:", counter)
	mu.Unlock()

	// 模拟耗时操作
	time.Sleep(time.Millisecond * 100)
}

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go increment(&wg)
	}
	wg.Wait()
	fmt.Println("Final counter:", counter)
}

在上面的代码中,counter 是一个被多个goroutine共享的变量,通过 sync.Mutex mu 来保证每次只有一个goroutine能够修改 counter 的值。

注意,由于 sync.Mutex 的具体实现(包括其内部状态)可能会随着Go语言的版本更新而变化,因此上面的“状态”分类主要是为了理解和讨论的目的,而不是基于 sync.Mutex 的内部实现细节。

回到顶部