>> For long-running tasks, if they are I/O bound you can use non-blocking I/O and event loops. If they are CPU bound, then use threads or separate processes. The two techniques can be combined to scale well across multiple cores.
>That combining is what M:N threading is. Green threads are application level threads. "threads" are OS level threads. M:N threading is the ability to take M application level ("green") threads, and schedule them on N actual threads.
More or less. I would say that manually threading continuations through async calls doesn't count as M:N. Not even when done via semi-automatically via the stack-less coroutines which are popular on recent languages as they are a very leaky abstraction.
I would even argue that a proper M:N system should have, if not full preemption, at least a best effort attempt at guaranteeing forward progress by implicit insertion of yields.