package mainimport "fmt"func sum(a []int, c chan int) { sum := 0 for _, v := range a { sum += v } c <- sum // send sum to c}func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[len(a)/2:], c) go sum(a[:len(a)/2], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y)}x, y := <-c, <-c // receive from c为什么这一行总是打印相同的结果?我认为应该是 50/50 的机会打印 17 -5 12 或 -5 17 12我觉得两个goroutine应该是并行的提前致谢!package mainimport "fmt"import "time"import "math/rand"func sum(a []int, c chan int) { sum := 0 for _, v := range a { sum += v } time.Sleep(time.Millisecond * time.Duration(rand.Intn(1000))) c <- sum // send sum to c}func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[len(a)/2:], c) go sum(a[:len(a)/2], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y)}我让线程进入睡眠状态,但同样的事情发生了。我还在纠结。
1 回答
狐的传说
TA贡献1804条经验 获得超3个赞
在这种情况下,假设它应该是 50/50 的机会是不正确的。需要明确的是,我并不是建议它应该始终是一个或另一个,而是您不应该期望每次程序运行时它都会改变。该行为不一定是随机的(甚至是伪随机的)。
goroutine 的保证不是它会被安排在一个随机的未来时间,而是它会在未来的某个时间运行。如果调度器的当前实现决定将 goroutines 放在一个简单的队列中,它不会自动意味着它被破坏了。对于您的特定代码的情况,如果您在不同的地方粘贴几个time.Sleep
s 或fmt.Printf
s,您有时可能会看到顺序发生变化。
我想知道您是否将 Go 的调度程序对下一个 goroutine 的选择select
与与通道一起使用时记录的伪随机行为混淆了。那里的行为被定义为随机的,正确地说行为应该有 50/50 的机会。
据我所知,运行时选择哪个 goroutine 并不是随机的。这不是说它不能是随机的,而是说它不应该是随机的。
重要的是你的代码不应该关心 goroutine 的调度顺序。无论它总是像队列一样有序,或向后(堆栈),或随机,或其他(可能是现实)。
- 1 回答
- 0 关注
- 157 浏览
添加回答
举报
0/150
提交
取消