Goroutines are preemptive only to the runtime scheduler. You, the application developer merely using the language, cannot directly preempt a goroutine.
This makes goroutines effectively cooperative still from the perspective of the developer. The preemptive runtime "just" prevents things like user code starving out the garbage collector. To interrupt a goroutine, your options are generally limited to context cancelation and closing the channel or socket being read, if any. And the goroutine may still refuse to exit (or whatever else you want it to do), though that's largely up to how you code it.
This difference is especially stark when compared with Erlang/BEAM where you can directly address, signal, and terminate its lightweight processes.
Exactly, thank you. I knew that the runtime gained the ability to preempt but the clear fact that you cannot get a handle to a goroutine (eg `gr := go fn()` is proof you have no way to take advantage of this ability as a user.
This makes goroutines effectively cooperative still from the perspective of the developer. The preemptive runtime "just" prevents things like user code starving out the garbage collector. To interrupt a goroutine, your options are generally limited to context cancelation and closing the channel or socket being read, if any. And the goroutine may still refuse to exit (or whatever else you want it to do), though that's largely up to how you code it.
This difference is especially stark when compared with Erlang/BEAM where you can directly address, signal, and terminate its lightweight processes.