为什么通道会受到互斥锁的影响?

时间:2021-03-02 07:19:49

标签: go mutex

我不知道为什么使用互斥锁时 c <- i 会起作用。

因为 rwMutex.Lock() 函数的第一行中有 second()

如果 mutex 不在通道中工作,则无法理解以下输出值。
输出值从 1 开始依次排列。

  1. 执行go second(...)
  2. 执行rwMutex.Lock()
  3. 因此 c <- i 不会运行,因为写入已锁定!
  4. 但是 num := <-c 正在工作。

ma​​in.go

var (
    dataSendChannel = make(chan int)
    rwMutex         = new(sync.RWMutex)
)

func main() {
    go first(dataSendChannel)
    time.Sleep(time.Second * 100)
}

func first(c chan<- int) {
    for i := 1; i <= 10; i++ {
        go second(dataSendChannel)
        c <- i
    }
}

func second(c <-chan int) {
    rwMutex.Lock()
    num := <-c
    time.Sleep(time.Duration(10-num) * time.Second)
    fmt.Println("[NUM] : ", num)
    rwMutex.Unlock()
}

输出

[NUM] :  1
[NUM] :  2
[NUM] :  3
[NUM] :  4
[NUM] :  5
[NUM] :  6
[NUM] :  7
[NUM] :  8
[NUM] :  9
[NUM] :  10

这是不使用时的输出值 mutex .

ma​​in.go

func second(c <-chan int) {
    num := <-c
    time.Sleep(time.Duration(10-num) * time.Second)
    fmt.Println("[NUM] : ", num)
}

输出

[NUM] :  10
[NUM] :  9
[NUM] :  8
[NUM] :  7
[NUM] :  6
[NUM] :  5
[NUM] :  4
[NUM] :  3
[NUM] :  2
[NUM] :  1

在通道上接收到一个数据后互斥量是否起作用?

1 个答案:

答案 0 :(得分:1)

当您使用互斥锁锁定变量 dfeval 时,您将阻止后续 goroutine 锁定互斥锁,因为它尚未解锁。

因此,第二个 goroutine 真的等到第一个 goroutine 完成睡眠(9 秒)然后打印数字 1。只有在那个时刻,第二个 goroutine 才能锁定互斥锁并写入变量 num,但是第三个还不能访问,所以它再次等待,直到第二个 goroutine 打印数字等等。

没有互斥锁,第一个goroutine休眠的时间最长,并且不会阻止其他人执行和写入num,所以它打印最新的,其他人可以先做他们的工作,因为睡眠时间和更快完成。

如果你删除 sleep ,它在两种情况下的效果都是一样的。

num
相关问题