Question

Please correct me if I am wrong. As long as I know, goroutine works roughly similar to threads. So If I spawn the same function with different parameters prefixing with go. It should work perfectly fine ?

package main

import "fmt"


func f(from string) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }
}

func main() {
    go f("direct")
    go f("redirect")
    //var input string
    //fmt.Scanln(&input)

}

Actual Output:

rahul@g3ck0:~/programs/go$ go run goroutine.go 
rahul@g3ck0:~/programs/go$ 

I just get back prompt.

Expected output:

direct : 0
direct : 1
direct : 2
redirect : 0
redirect : 1
redirect : 2

Not necessarily in the same order.
Not able to understand this strange behaviour. Am I missing something ?

EDIT: Adding a Scan statement resolves it. But is there any better way of doing it ?

Was it helpful?

Solution

When main exits, the program terminates regardless of the state of other goroutines. You can test this by adding select{} at the end of your main function. This will cause main to never exit and you will see the other goroutines run.

If you want your program to exit cleanly (without a deadlock) when both goroutines complete, you need to use something like a channel or sync.Waitgroup to coordinate main ending when everything is complete.

Example using sync.Waitgroup:

package main

import (
    "fmt"
    "sync"
)

func f(from string, wg *sync.WaitGroup) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }

    wg.Done()
}

func main() {
    wg := new(sync.WaitGroup)
    wg.Add(2)

    go f("direct", wg)
    go f("redirect", wg)

    wg.Wait()
}

Example using channels:

package main

import (
    "fmt"
)

func f(from string, ch chan<- bool) {
    for i := 0; i < 3; i++ {
        fmt.Println(from, ":", i)
    }

    ch <- true
}

func main() {
    ch := make(chan bool)

    go f("direct", ch)
    go f("redirect", ch)

    <-ch
    <-ch
}

OTHER TIPS

As stated above the select{} in the end makes sure output is displayed, but you cannot expect the go routines to run in a special order.

If you run parallell go routines there is never any guarantee in what order they will run. You cannot except them to run in a sequential order, because they run in parallell!

You might get the expected output time after time on one machine, but there is no guarantee that the printouts come in order every time on any given machine!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top