Few C implementations of these applications use M:N threading. M:N threading was tried early on in Linux's history and was abandoned for a reason. It is not a requirement for implementing those applications; in fact, it'll always be suboptimal from a performance point of view, especially in low-level languages like Rust. (Note that I'm not saying it's not fast enough for most applications, or that it was the wrong choice for Go, just that it's not
optimal.)
I think the right solution is something like async/await to make truly asynchronous programming palatable. But in the meantime, 1:1 threading is really not that bad on Linux, because the kernel is very optimized.