我不知道为什么使用互斥锁时 c <- i
会起作用。
因为 rwMutex.Lock()
函数的第一行中有 second()
。
如果 mutex
不在通道中工作,则无法理解以下输出值。
输出值从 1 开始依次排列。
go second(...)
rwMutex.Lock()
c <- i
不会运行,因为写入已锁定!num := <-c
正在工作。main.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
.
main.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
在通道上接收到一个数据后互斥量是否起作用?
答案 0 :(得分:1)
当您使用互斥锁锁定变量 dfeval
时,您将阻止后续 goroutine 锁定互斥锁,因为它尚未解锁。
因此,第二个 goroutine 真的等到第一个 goroutine 完成睡眠(9 秒)然后打印数字 1。只有在那个时刻,第二个 goroutine 才能锁定互斥锁并写入变量 num
,但是第三个还不能访问,所以它再次等待,直到第二个 goroutine 打印数字等等。
没有互斥锁,第一个goroutine休眠的时间最长,并且不会阻止其他人执行和写入num
,所以它打印最新的,其他人可以先做他们的工作,因为睡眠时间和更快完成。
如果你删除 sleep ,它在两种情况下的效果都是一样的。
num