golang:协程和通道的奇怪问题
golang: strange issue with coroutines and channels
我写了一个测试代码,但不明白为什么会得到这个结果。
我的 sub()
应该更新或 return counter
,基于频道值
send 1 = counter++
send 0 = return counter
我开始了 10 个围棋例程 con()
。
他们应该简单地发送许多 1 到频道(这个增加计数器)
我等待 1 秒并将 0 发送到通道。我应该得到什么价值?
我想首先,我得到一个 "random" 值,
但我得到 100000(好的 10x 10000 比 1 秒快)
现在我变了
for i:=0; i < 10; i++ {
到
for i:=0; i < 10000; i++ {
现在我的 returned 值为 1
为什么!?
现在取消 main()
中 fmt.Println(counter)
的注释。
如您所见,计数器工作并且有这个 "random" number
package main
import (
"fmt"
"time"
)
var ch chan int = make(chan int)
var counter int
func main() {
go sub()
for i:=0; i < 10; i++ { //change to 10000
go con()
}
time.Sleep(1000 * time.Millisecond)
ch <- 0
fmt.Println(<- ch)
//fmt.Println(counter) //uncomment this
}
func sub() {
for c := range ch {
if c == 0 { ch <- counter }
if c == 1 { counter++ }
}
}
func con() {
for i := 0; i < 10000; i++ {
ch <- 1
}
}
有 2 个通道,这项工作:
package main
import (
"fmt"
"time"
)
var ch chan int = make(chan int)
var ch2 chan int = make(chan int)
var counter int
func main() {
go sub()
for i:=0; i < 10000; i++ { //change to 10000
go con()
}
time.Sleep(1000 * time.Millisecond)
ch2 <- 0
fmt.Println(<- ch2)
//fmt.Println(counter) //uncomment this
}
func sub() {
for ;; {
select {
case <- ch:
counter++
case <- ch2:
ch2 <- counter
}
}
}
func con() {
for i := 0; i < 10000; i++ {
ch <- 1
}
}
我写了一个测试代码,但不明白为什么会得到这个结果。
我的 sub()
应该更新或 return counter
,基于频道值
send 1 = counter++
send 0 = return counter
我开始了 10 个围棋例程 con()
。
他们应该简单地发送许多 1 到频道(这个增加计数器)
我等待 1 秒并将 0 发送到通道。我应该得到什么价值?
我想首先,我得到一个 "random" 值, 但我得到 100000(好的 10x 10000 比 1 秒快)
现在我变了
for i:=0; i < 10; i++ {
到
for i:=0; i < 10000; i++ {
现在我的 returned 值为 1
为什么!?
现在取消 main()
中 fmt.Println(counter)
的注释。
如您所见,计数器工作并且有这个 "random" number
package main
import (
"fmt"
"time"
)
var ch chan int = make(chan int)
var counter int
func main() {
go sub()
for i:=0; i < 10; i++ { //change to 10000
go con()
}
time.Sleep(1000 * time.Millisecond)
ch <- 0
fmt.Println(<- ch)
//fmt.Println(counter) //uncomment this
}
func sub() {
for c := range ch {
if c == 0 { ch <- counter }
if c == 1 { counter++ }
}
}
func con() {
for i := 0; i < 10000; i++ {
ch <- 1
}
}
有 2 个通道,这项工作:
package main
import (
"fmt"
"time"
)
var ch chan int = make(chan int)
var ch2 chan int = make(chan int)
var counter int
func main() {
go sub()
for i:=0; i < 10000; i++ { //change to 10000
go con()
}
time.Sleep(1000 * time.Millisecond)
ch2 <- 0
fmt.Println(<- ch2)
//fmt.Println(counter) //uncomment this
}
func sub() {
for ;; {
select {
case <- ch:
counter++
case <- ch2:
ch2 <- counter
}
}
}
func con() {
for i := 0; i < 10000; i++ {
ch <- 1
}
}