0

I'm trying to experiment with go routines about who gets the message first. However, when the main goroutine terminates, some go routines are still hanging around. I see this through the stack trace from panic. However, If I add time.Sleep they all terminate. I guess this is because, when the main go routines ends, Go runtime couldn't find time to terminate the others.

    package main

    import (
        "fmt"
        "time"
    )

    func main() {
        for i := 0; i < 1000000; i++ {
            algo()
        }

        // without this, some goroutines do not terminate
        // time.Sleep(time.Second)

        panic("")
    }

    func algo() {
        c := make(chan int)
        wait := make(chan bool)

        go racer(1, wait, c)
        go racer(2, wait, c)
        go racer(3, wait, c)
        go racer(4, wait, c)
        go racer(5, wait, c)

        // who gets it first
        c <- 5
        close(wait)
    }

    func racer(name int, wait chan bool, c chan int) {
        select {
        case <-wait:
        case v := <-c:
            fmt.Println(name, ":", v)
        }
    }

1 Answers1

0

That's exactly what sync.WaitGroup is for. Here's a toy example taken from this blog post:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    messages := make(chan int)
    var wg sync.WaitGroup

    // you can also add these one at 
    // a time if you need to 

    wg.Add(3)
    go func() {
        defer wg.Done()
        time.Sleep(time.Second * 3)
        messages <- 1
    }()
    go func() {
        defer wg.Done()
        time.Sleep(time.Second * 2)
        messages <- 2
    }() 
    go func() {
        defer wg.Done()
        time.Sleep(time.Second * 1)
        messages <- 3
    }()
    go func() {
        for i := range messages {
            fmt.Println(i)
        }
    }()

    wg.Wait()
}
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • Thank you Eli, I'm aware of `WaitGroup`. However, it was more like a theoretical question: "Am I right or not?". The runtime couldn't really terminate the go routine because the main go routine quits before them or not?? – John Fitzgerald May 07 '19 at 20:34
  • @JohnFitzgerald: when I lower the iteration counter `i` seems like everything terminates alright. I think you overcomplicated your example. algo() runs one by one (because `c<-5` blocks). Try to simplify your example to answer your theoretical question – Eli Bendersky May 07 '19 at 20:39
  • Thanks Eli, that was intentional. I've been trying to see receiving a message happens randomly or in an order. I thought that if I run it several times, I can detect that. The Go Spec doesn't say anything about this. – John Fitzgerald May 07 '19 at 20:41
  • @JohnFitzgerald: I suggest you synthesize a simpler example and ask a new question. It's not clear what you're asking here, to be honest – Eli Bendersky May 07 '19 at 20:42