Callback based approaches 37 Callback based approaches Note! This is another example of M:N threading. Many tasks can run concurrently on one OS thread. Each task consists of a chain of callbacks. Y ou probably already know what we're going to talk about in the next paragraphs from Java Script, which I assume most know. The whole idea behind a callback-based approach is to save a pointer to a set of instructions we want to run later together with whatever state is needed. In Rust, this would be a closure. Implementing callbacks is relatively easy in most languages. They don't require any context switching or pre-allocated memory for each task. However, representing concurrent operations using callbacks requires you to write the program in a radically different way from the start. Re-writing a program that uses a normal sequential program flow to one using callbacks represents a substantial rewrite, and the same goes the other way. Callback-based concurrency can be hard to reason about and can become very complicated to understand. It's no coincidence that the term “callback hell” is something most Java Script developers are familiar with. Since each sub-task must save all the state it needs for later, the memory usage will grow linearly with the number of callbacks in a task. Advantages Easy to implement in most languages No context switching Relatively low memory overhead (in most cases) Drawbacks Memory usage grows linearly with the number of callbacks. Programs and code can be hard to reason about. It's a very different way of writing programs and it will affect almost all aspects of the program since all yielding operations require one callback. Ownership can be hard to reason about. The consequence is that writing callback-based programs without a garbage collector can become very difficult.