为什么通道会受到互斥量的影响?
Why is the channel affected by mutex?
我不知道为什么 c <- i
在使用互斥量时起作用。
因为second()
函数的第一行有rwMutex.Lock()
如果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
通道上收到一个数据后互斥量是否起作用?
当您使用互斥体锁定变量 num
时,您将阻止后续的 goroutines 锁定互斥体,因为它尚未解锁。
因此,第二个 goroutine 真正等到第一个 goroutine 完成休眠(9 秒),然后打印数字 1。只有在那一刻,第二个 goroutine 才能锁定互斥锁并写入变量 num
, 但第三个还不能访问,所以它再次等待,直到第二个 goroutine 打印数字等等。
没有mutex,第一个goroutine休眠时间最长,不会阻止其他人执行和写入num
,所以它打印最新的,其他人可以先做他们的工作,因为睡眠较少时间,完成得更快。
如果删除睡眠,两种情况下效果相同。
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()
}
我不知道为什么 c <- i
在使用互斥量时起作用。
因为second()
函数的第一行有rwMutex.Lock()
如果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
通道上收到一个数据后互斥量是否起作用?
当您使用互斥体锁定变量 num
时,您将阻止后续的 goroutines 锁定互斥体,因为它尚未解锁。
因此,第二个 goroutine 真正等到第一个 goroutine 完成休眠(9 秒),然后打印数字 1。只有在那一刻,第二个 goroutine 才能锁定互斥锁并写入变量 num
, 但第三个还不能访问,所以它再次等待,直到第二个 goroutine 打印数字等等。
没有mutex,第一个goroutine休眠时间最长,不会阻止其他人执行和写入num
,所以它打印最新的,其他人可以先做他们的工作,因为睡眠较少时间,完成得更快。
如果删除睡眠,两种情况下效果相同。
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()
}