Hello,
I wrote the following code.
package main
import (
"time"
"fmt"
)
var ch chan int
var ptimer map[string]*time.Timer
var m map[string]int
var startTime int64
func fn(name string, i int) {
fmt.Println("this my name:", name)
flag := false
for {
endTime := time.Now().UnixNano()
fmt.Println(" in for duration:", float64((endTime-startTime)))
select {
case tmp := <-ch:
fmt.Println(" this is ch, tmp:", tmp)
flag = true
break
case <-ptimer[name].C:
_, ok := m[name]
if !ok{
fmt.Println(" ", name, "not in m")
flag = true
break
}
if 1==1 {
fmt.Println(" this is in 1==1!!!!!!!!!!!!!!!!!!!!")
ptimer[name].Reset(time.Second*20)
break
}
}
if flag == true {
fmt.Println(" in flag == true no.:", i, "\n")
break
}
}
}
func fib(a int) int {
if a==0 {
return 0
}else if a==1{
return 1
}else {
return fib(a-1)+fib(a-2)
}
}
func main() {
fmt.Println("this is in main")
name := "hello"
m = make(map[string]int)
ptimer = make(map[string]*time.Timer)
startTime := time.Now().UnixNano()
i:=1
for{
m[name] = 30
ptimer[name] = time.NewTimer(time.Second*20)
go fn(name, i)
fmt.Println("fib:", fib(m[name]))
endTime := time.Now().UnixNano()
fmt.Println("duration:", float64((endTime-startTime)))
delete(m, name)
ch = make(chan int, 1)
ch <- i
fmt.Println("after send exit_overtime\n")
i++
time.Sleep(time.Second)
}
}
When I set the parameter of the fib
function to 10, everything goes well.
However, when I set it to 30, something unexpected happens. I find that the first fn
goroutine, which the argument i
is 1, cannot receives the ch
channel message.
I print some information during the execution. It shows that when the parameter is 30, it will first enter the for loop in fn
function. After that , it then finishes the execution of fib
function and sends i
to the ch
channel. In the situation that the parameter is ‘10’, it can finish fib
caculation before entering the fn
function. So, the first ‘fn’ goroutine can receive ‘ch’ channel and exit.
The problem is that the first ‘fn’ goroutine can only exit when the ptimer
times up. If I don’t have this ptimer, the first fn
goroutine can never exit?
I wonder why the execution of the for loop in fn
prior to the main function send i
to ch
channel can make the first fn
cannot receive the ch
. By the way, the message first ch
receive will be received in the second fn
goroutine.
And I wonder is there any solution for this problem? To be more specific, under the premise of not changing the sequence, how the first fn
goroutine exit when sending i
to ch
at the first time. The sequence is that the go fn(name, i)
need to prior to fib
execution.