鍍金池/ 問答/GO  網(wǎng)絡安全  HTML/ go語言里面關于channel和select的問題

go語言里面關于channel和select的問題

我有段代碼是啟動了一個goroutine,在一個無限循環(huán)中給一個channel數(shù)組中一個隨機元素賦值,主線程使用select從中取值,但是通過打印我發(fā)現(xiàn),goroutine執(zhí)行兩次循環(huán)后,切換到主線程,,特別有規(guī)律,這是為什么?這種切換不是cpu隨機的嗎?怎么會有這種規(guī)律性?(可以看x和y的打印結果)
代碼如下:
package main

import (

"math/rand"
"fmt"
"time"

)

func main() {

rand.Seed(time.Now().UTC().UnixNano())
channels := make([]chan bool, 6)
for i := range channels {
    channels[i] = make(chan bool)
}
go func() {
    for {
        y := rand.Intn(6)

        fmt.Printf("y:%d\n", y)
        channels[y] <- true

    }
}()
for i := 0; i < 36; i++ {
    var x int
    select {
    case <-channels[0]:
        x = 1
    case <-channels[1]:
        x = 2
    case <-channels[2]:
        x = 3
    case <-channels[3]:
        x = 4
    case <-channels[4]:
        x = 5
    case <-channels[5]:
        x = 6
    }
    fmt.Printf("x:%d\n", x)
}
fmt.Println()

}
輸出結果:
y:2
y:2
x:3
x:3
y:1
y:2
x:2
x:3
y:0
y:2
x:1
x:3
y:1
y:2
x:2
x:3
y:1
y:5
x:2
x:6
y:0
y:1
x:1
x:2
y:4
y:5
x:5
x:6
y:1
y:4
x:2
x:5
y:0
y:5
x:1
x:6
y:5
y:1
x:6
x:2
y:2
y:0
x:3
x:1
y:3
y:3
x:4
x:4
y:1
y:2
x:2
x:3
y:1
y:3
x:2
x:4
y:5
y:2
x:6
x:3
y:4
y:0
x:5
x:1
y:2
y:1
x:3
x:2
y:4
y:1
x:5
x:2

Process finished with exit code 0

回答
編輯回答
荒城

cpu 和 goroutine 默認情況下并不是 1:1 的關系,對各個 goroutine 的調(diào)度是 go runtime 的調(diào)度器決定的

2017年3月24日 22:21
編輯回答
朕略傻

因為你用的阻塞模式, 兩個協(xié)程形成互相依賴.

發(fā)送方 channels[y] <- true 被阻塞, 直到接收方 case <-channels[x]: 接收了, 反向亦然.

你可以設置 channel 緩存觀察不一樣的結果, 示例如下

package main
import (
    "fmt"
    "math/rand"
    "time"
)
func main() {
    rand.Seed(time.Now().UTC().UnixNano())
    channels := make([]chan bool, 6)
    for i := range channels {
        channels[i] = make(chan bool, 6)
    }
    go func() {
        for i := 0; i < 36; i++ {
            y := rand.Intn(6)
            fmt.Printf("y:%d\n", y)
            channels[y] <- true
        }
    }()
    for i := 0; i < 36; i++ {
        var x int
        select {
        case <-channels[0]:
            x = 1
        case <-channels[1]:
            x = 2
        case <-channels[2]:
            x = 3
        case <-channels[3]:
            x = 4
        case <-channels[4]:
            x = 5
        case <-channels[5]:
            x = 6
        }
        fmt.Printf("x:%d\n", x)
    }
    fmt.Println()
}
2017年12月10日 20:04
編輯回答
扯機薄

這種情況可能是兩個goroutine并行執(zhí)行

2018年8月7日 10:21