Timeout is quite common practice in programming. For example, Listen function in internet connection with a timeout may just close the connection and Listen thread as silence persists for some period, like 60 seconds.
I found it very hard to implement such a general shutdown feature of a thread/goroutine on such I/O functions, here is one unsuccessful try, which I want to stop the whole in 9 seconds but it does not function as I wanted:
package main
import (
"fmt"
"time"
)
func wait(){
time.Sleep(5 * time.Second)
fmt.Println("wait 1st signal")
time.Sleep(5 * time.Second)
fmt.Println("wait 2nd signal")
}
func main() {
ticker := time.NewTicker(3 * time.Second)
i := 0
for{
select{
case <- ticker.C:
i++
fmt.Printf("ticker rings %d\n", i)
if i==3{
return
}
default:
wait()
}
}
}
The result is to wait whole 30 seconds:
wait 1st signal
wait 2nd signal
ticker rings 1
wait 1st signal
wait 2nd signal
ticker rings 2
wait 1st signal
wait 2nd signal
ticker rings 3
An online course suggests to wrap up the wait/Listen function with a channel (which would return something instead of nothing above)
go func(){
resultChan <- Listen()
}()
select{
case a := <- resultChan:
//analyze a
case <-ticker.C:
//might break or return
}
But this recipe obviously only kill the select goroutine rather than the anonymous goroutine that actually runs Listen function. My question is - how to kill the waiting or listening goroutine from outside?