Have loook at this contrived example:
package main
import \"fmt\"
func printElo() {
fmt.Printf(\"Elo\\n\")
}
func printHello() {
fmt.Printf(\"Hel
If you want just to play with results you can use "hack" with waiting for input:
package main
import (
"fmt"
"bufio"
"os"
)
func printElo() {
fmt.Printf("Elo\n")
}
func printHello() {
fmt.Printf("Hello\n")
}
func main() {
fmt.Printf("This will print.")
i := 0
for i < 10 {
go printElo()
go printHello()
i++
}
reader := bufio.NewReader(os.Stdin)
reader.ReadString('\n')
}
If want to learn how to do synchronization read about sync package:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func printElo() {
fmt.Printf("Elo\n")
wg.Done()
}
func printHello() {
fmt.Printf("Hello\n")
wg.Done()
}
func main() {
fmt.Printf("This will print.")
i := 0
for i < 10 {
wg.Add(2)
go printElo()
go printHello()
i++
}
wg.Wait()
}
Simplest, cleanest and "scalable" way to do it is to use a sync.WaitGroup:
var wg = &sync.WaitGroup{}
func printElo() {
defer wg.Done()
fmt.Printf("Elo\n")
}
func printHello() {
defer wg.Done()
fmt.Printf("Hello\n")
}
func main() {
fmt.Printf("This will print.")
i := 0
for i < 10 {
wg.Add(1)
go printElo()
wg.Add(1)
go printHello()
i++
}
wg.Wait()
}
Output (try it on the Go Playground):
This will print.Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Hello
Elo
Simple "rules" to follow when doing it with sync.WaitGroup
:
WaitGroup
to other functions (and not use a global variable), you must pass a pointer to it, else the WaitGroup
(which is a struct) would be copied, and the Done()
method called on the copy wouldn't be observed on the originalAs already mentioned sync.WaitGroup
is a right way in production code. But when developing for test and debug purposes you can just add select{}
statement at the end or the main()
.
func main(){
go routine()
...
select{}
}
main()
then never returns and you would kill it with for example Ctrl-C
. It isn't idiomatic, never used in production, but just very quick easy hack when developing.
You can use sync package and take a look at waitgroups
. You can take a look at a working Goplayground I set up.
Essentially
package main
import (
"fmt"
"sync"
)
//Takes a reference to the wg and sleeps when work is done
func printElo(wg *sync.WaitGroup) {
fmt.Printf("Elo\n")
defer wg.Done()
}
//Takes a reference to the wg and sleeps when work is done
func printHello(wg *sync.WaitGroup) {
fmt.Printf("Hello\n")
defer wg.Done()
}
func main() {
//Create a new WaitGroup
var wg sync.WaitGroup
fmt.Println("This will print.")
for i := 0; i < 10; i++ {
//Add a new entry to the waitgroup
wg.Add(1)
//New Goroutine which takes a reference to the wg
go printHello(&wg)
//Add a new entry to the waitgroup
wg.Add(1)
//New Goroutine which takes a reference to the wg
go printElo(&wg)
}
//Wait until everything is done
wg.Wait()
}