How `select` statement in Go is able go ahead when a case is in progress?

Issue

This Content is from Stack Overflow. Question asked by Parveen

You can try this code on Go Playground here: https://go.dev/play/p/BsXK_4tJnca?v=goprev

package main

import (
    "fmt"
    "time"
)

func simulateWork(v int) int {
    start := time.Now()
    fmt.Println("Begin: goroutine", v, "sleeping for", v, "seconds")
    time.Sleep(time.Duration(v) * time.Second)
    elapsed := time.Since(start)
    fmt.Println("End: goroutine", v, "woke up after sleeping for", elapsed, "seconds")
    return v
}

func main() {
    done := make(chan struct{})
    result := make(chan int)
    defer close(result)

    for i := 3; i <= 5; i++ {
        go func(v int) {
            select {
            case result <- simulateWork(v):
            case <-done:
            }
        }(i)
    }
    _ = <-result // discard
    close(done)
}

The output of this code is:

Begin: goroutine 5 sleeping for 5 seconds
Begin: goroutine 3 sleeping for 3 seconds
Begin: goroutine 4 sleeping for 4 seconds
End: goroutine 3 woke up after sleeping for 3s seconds

Program exited.

As the output shows, select in all the goroutines go ahead with result <- simulateWork(v) case but when goroutine 3 is done the main goroutine close the done channel, and the goroutine 4 and goroutine 5 finishes early, while result <- simulateWork(v) case is already in progress.

How select statement is able to go ahead, without waiting for the case (it has selected) to finish ?



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?