On Fri, Jan 17, 2014 at 12:54 AM, Gavin Lambert
On 17/01/2014 02:44, Quoth Oliver Kowalke:
As I wrote before - with thread you would have to scatter your code with callbacks. With fibers you don't - you could write the code as it would by synchronous operations. That makes the code easier to read and understandable.
Boost.Asio already supports using Boost.Coroutine for that purpose; an extra library seems unnecessary if that is your target.
What if you're using an asynchronous API that's not Boost.Asio? What if you're using several different async APIs? Wouldn't you want something like future and promise to interface between your coroutine and an arbitrary asynchronous API? Then there's the lifespan question. In a classic coroutine scenario, you instantiate a coroutine object, you chat with it for a bit, then you destroy it. But launching a "cooperatively context-switched thread" is more of a fire-and-forget operation. Who owns the object? Who cleans up when it's done? Then there's control flow. A coroutine has a caller. When it context-switches away, it specifically resumes that caller. What if you have several different coroutines you're using as cooperative threads, and you want to run whichever of them is ready next? Clearly all of this can be done with coroutines, yes. (Fiber does build it on coroutines!) But it's a whole additional abstraction layer. Must every developer facing this kind of use case build that layer by hand?
My understanding is that the new thing that Fibers tries to bring to the table is std::thread-like cross-fiber synchronisation. Which is something that only matters if you have fibers running in multiple threads, and does not seem related to the use case you're mentioning above, unless I'm missing something.
Consider a producer fiber obtaining input from some async source, pumping items into a queue. That queue is consumed by several different consumer fibers, each interacting with an async sink. All of it is running on a single thread. That's just one example.