Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang `select` seems not fair [duplicate]

Tags:

concurrency

go

I am a beginner of Golang, I read from the official spec of select that I will do uniform pseudo-random when more of communications can proceed, but when I tried the following code

package main

import (
    "fmt"
)

func main() {

    // For our example we'll select across two channels.
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        for {
            c1 <- "one"
        }
    }()
    go func() {
        for {
            c2 <- "two"
        }
    }()

    for i := 0; i < 100; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

It always print 'received two', seems not to be a random result, so where am I wrong?

The code can be test here.

like image 696
kemiya Avatar asked Jan 16 '18 03:01

kemiya


2 Answers

the problem is you run it on go playground,, On the Go Playground, GOMAXPROCS is 1,, This means one goroutine is executed at a time, and if that goroutine does not block, the scheduler is not forced to switch to other goroutines.

So, you should run it in your local machine, to see the real results

When you run it locally, most likely GOMAXPROCS will be greater than 1 as it defaults to the number of CPU cores available (since Go 1.5). So it doesn't matter if you have a goroutine executing an endless loop, another goroutine will be executed simultaneously, which will be the main(), and when main() returns, your program terminates; it does not wait for other non-main goroutines to complete

like image 174
Fendi jatmiko Avatar answered Oct 17 '22 12:10

Fendi jatmiko


Depending on the Go version used, it might be; see this issue. It should be fixed in Go 1.10 (regarding this one, it is fixed in Go 1.9.2 but I have not tested).

like image 34
Kaveh Shahbazian Avatar answered Oct 17 '22 10:10

Kaveh Shahbazian