← Back to context

Comment by seabrookmx

18 hours ago

C# and Rust (via Tokio) both have M:N threading. They both use a work-stealing algorithm to map many tasks onto a finite thread pool. But you're correct that they are cooperative via async/await, not pre-emptive.

Very curious how much Go wins by this. How worse would typical Go programs run with pre-emption disabled?

  • You can try this yourself: GODEBUG=asyncpreemptoff=1

    Also platforms like Wasm still do Mx1 scheduling without async preemption, where Gosched is required at places.

    E.g.: my "transpiled" SQLite driver takes special care to make sure long running SQL queries (and the busy handler) can be canceled with contexts even on platforms without async preemption.

  • I believe it’s more about robustness than performance in typical cases. Without pre-emption, there’s always a risk of one goroutine using disproportionate CPU time if it gets into an infinite (or just very long) loop without doing any IO.