107 // AfterFunc waits for the duration to elapse and then calls f 108 // in its own goroutine. It returns a Timer that can 109 // be used to cancel the call using its Stop method. 110 func AfterFunc(d Duration, f func()) *Timer { 111 t := &Timer{ 112 r: runtimeTimer{ 113 when: when(d), 114 f: goFunc, 115 arg: f, 116 }, 117 } 118 startTimer(&t.r) 119 return t 120 } 121 122 func goFunc(now int64, arg interface{}) { 123 go arg.(func())() 124 }Is there any way that I can cancel function call without it being run on goroutine? For example, time.CancelFunc(time.Millisecond, fn) will run fn immediately and cancel the function after 1ms. This is different than time.AfterFunc(0, fn) which runs fn after 0 ms but still on its own goroutine, whereas time.CancelFunc will run fn on the main, I mean not on the separate goroutine. It might be useful to cancel a function that runs forever in its recursive call.
func main() {ticker := time.NewTicker(time.Second)killme := make(chan bool)go func() {fmt.Println("starting counter")defer fmt.Println("all done")cnt := 0for {select {case <-killme:returncase <-ticker.C:cnt++fmt.Println(cnt)}}}()time.Sleep(time.Second * 10)killme <- true}
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
I'm not sure if it's possible to kill an arbitrary goroutine or not, but this isn't how you should structure your code. If you want a goroutine to be cancelable you need to use channels to communicate between them. For example:func main() {ticker := time.NewTicker(time.Second)killme := make(chan bool)go func() {fmt.Println("starting counter")defer fmt.Println("all done")cnt := 0for {select {case <-killme:returncase <-ticker.C:cnt++fmt.Println(cnt)}}}()time.Sleep(time.Second * 10)killme <- true
Stop turns off a ticker. After Stop, no more ticks will be sent. Stop does not close the channel, to prevent a read from the channel succeeding incorrectly.
func example() {t := time.NewTicker(time.Millisecond)defer t.Stop()s := make(chan struct{})
defer close(s)
go func() {for {select {case <-t.C:// do stuff herecase <-s:return}}}()time.Sleep(time.Millisecond)}
func main() {for i :=0; i<100000000; i++ {example()time.Sleep(time.Millisecond)}fmt.Scanln()}
func Odds(from, to int, quit <-chan struct{}) <-chan int {
c := make(chan int)
go func() {
defer close(c)
if from%2 == 0 {
from += 1
}
for i := from; i < to; i += 2 {
select {
case <-quit:
return
case c <- i:
}
}
}()
return c
}So when you do this case <-quit: return , does the goroutine not exist anymore or we only end the Odds function? --
func somethingSlow(c chan bool) {time.Sleep(time.Second)c <- true}
func main() {c := make(chan bool, 1) // use a buffer here so the send can happen even if no one is receivinggo somethingSlow(c)select {case value := <-c:fmt.Println("no timeout. got:", value)case <-time.After(time.Second):fmt.Println("timeout")}}