Go 为什么通道受互斥影响?

Go 为什么通道受互斥影响?,go,mutex,Go,Mutex,我不知道为什么c当您用互斥锁锁定变量num时,会阻止后续的goroutine锁定互斥锁,因为它尚未解锁 因此,第二个goroutine实际上会等到第一个goroutine完成睡眠(9秒),然后打印数字1。只有在这个时刻,第二个goroutine才能锁定互斥锁并写入变量num,但是第三个goroutine还不能访问,所以它会再次等待,直到第二个goroutine打印出数字,依此类推 如果没有互斥锁,第一个goroutine睡眠时间最长,并且它不会阻止其他人执行和写入num,因此它会打印最后一个go

我不知道为什么
c当您用互斥锁锁定变量
num
时,会阻止后续的goroutine锁定互斥锁,因为它尚未解锁

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

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

如果删除睡眠,则在这两种情况下的效果相同

package main

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

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
    fmt.Println("[NUM] : ", num)
    rwMutex.Unlock()
}
主程序包
进口(
“fmt”
“同步”
“时间”
)
变量(
dataSendChannel=make(chan int)
rwMutex=new(sync.rwMutex)
)
func main(){
先走(数据终端频道)
时间。睡眠(时间。秒*100)
}

func优先(c)您的输出是我期望看到的;通过添加互斥体,您正在阻止并发执行。如果您添加您期望发生的事情以及原因的详细信息,也许会有所帮助。@Brits我添加了一些expect-ocate
num
是局部变量,为什么不在另一个goroutine中使用
num
?我认为互斥体将变量锁定在中解除锁定
和解锁
,但现在我意识到,在解锁互斥锁之前,相同的goroutine不起作用。是的,没错。当互斥锁尚未解锁时,您无法再次锁定它,因此goroutine需要等待。如果您仍然不确定,中的示例可能会有所帮助。
[NUM] :  10
[NUM] :  9
[NUM] :  8
[NUM] :  7
[NUM] :  6
[NUM] :  5
[NUM] :  4
[NUM] :  3
[NUM] :  2
[NUM] :  1
package main

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

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
    fmt.Println("[NUM] : ", num)
    rwMutex.Unlock()
}