Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

First goroutine example, weird results

Tags:

go

goroutine

This example taken from tour.golang.org/#63

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}

The output

hello
world
hello
world
hello
world
hello
world
hello

Why world is printed only 4 times instead of 5 ?


Edit: The answer can be quoted from golang specification:

Program execution begins by initializing the main package and then invoking the function main. When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

like image 549
Salah Eddine Taouririt Avatar asked Sep 01 '25 22:09

Salah Eddine Taouririt


2 Answers

When your main function ends your program ends, i.e. all goroutines are terminated. Your main terminates before go say("world") is done. If you sleep some time at the end of main you should see the last world.

like image 131
Volker Avatar answered Sep 03 '25 21:09

Volker


Here is how you solve that synchronization problem properly - with sync.WaitGroup

Playground link

package main

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

func say(s string, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    wg := new(sync.WaitGroup)
    wg.Add(2)
    go say("world", wg)
    go say("hello", wg)
    wg.Wait()
    fmt.Println("All done")
}
like image 43
Nick Craig-Wood Avatar answered Sep 03 '25 20:09

Nick Craig-Wood