Is there a way to stop a long blocking function?

go

Solution

I reckon you can't do it: goroutines in Go are, in a sense, cooperative: until a goroutine actively tries to somehow figure out if it should exit, there's no way to force it to do so.

I'd say it's a feature in fact because if you could forcibly reap a long-running goroutine, you would be unable to be sure it exited cleanly, that is, properly released all resources it had acquired.

So either live with this (say, if your process wants to exit, just wait on that goroutine to finish) or restructure it so that it periodically checks whether it is signaled to quit. Or even consider offloading the task it performs to an external process (but note that while it's safe to kill a process with regard to releasing the resources it acquired from the OS, it's not safe with regard to external data that process might have been updating — such as files).

Problem

I have a function that run for minutes and I'm trying to find a way to stop it using a channel. I think I can't do it like I do in the following code since I think the `select` will only handle the `stop` case after the `default` is done. ``` package main import ( "fmt" "time" ) func main() { stop := make(chan int) go func() { for { select { case <-stop: fmt.Println("return") return default: fmt.Println("block") time.Sleep(5 * time.Second) // simulate a long running function fmt.Println("unblock") } } }() time.Sleep(1 * time.Second) stop <- 1 } ```

Original source