I'm newie to golang and studying the goroutine.
I wrote the simple code that divide the number using goroutine on purpose.
First of all, I give the base number and keep on dividing its number until it is not divisible
But, I change go split(n)
to split(n)
, it is not working like the following, is this why?
■ source code
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"strconv"
)
var next = make(chan int)
var quit = make(chan int)
func divide(n int) {
defer func(){ quit <- 1 }()
fmt.Println("[divide] n = " + strconv.Itoa(n))
r := n % 2
if r == 0 {
next <- n / 2
}
}
func execute() {
fmt.Println("[execute] start")
count := 0
end := false
for !end {
select {
case n := <- next:
count++
fmt.Println("[execute] n = " + strconv.Itoa(n) + ", count = " + strconv.Itoa(count))
go divide(n)
case _ = <- quit:
count--
fmt.Println("[execute] end. count = " + strconv.Itoa(count))
if count <= 0 {
end = true
}
}
}
fmt.Println("complete")
os.Exit(0)
}
func main() {
base := flag.Int("n", 1, "Input the number")
flag.Parse()
if *base <= 0 {
fmt.Println("please more than 1")
os.Exit(0)
}
go execute()
next <- *base
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndSearver:", err)
}
}
■ result(work fine)
$ go run main.go -n 6
[execute] start
[execute] n = 6, count = 1
[divide] n = 6
[execute] n = 3, count = 2
[execute] end. count = 1
[divide] n = 3
[execute] end. count = 0
complete
■ result(not work)
$ go run main.go -n 6
[execute] start
[execute] n = 6, count = 1
[divide] n = 6
Without go divide()
inside execute:
next
channel, calls divide
next
With go divide()
inside execute:
next
channel, starts divide
in new goroutine, continues waitingnext
next
, starts another goroutine, etc.Note that as soon as divide
writes to next
, it continues to write to quit
so you may receive multiple quit messages before everything is done.