History of Time: Asynchronous C++

By Steven Simpson

It is unusual to find software which does not have to perform I/O of some kind, be it talking to persistent storage devices or communicating between networked machines. These operations are typically categorised by the fact that they incur latency - time which your software must wait patiently before it can continue its work. In a world ever reliant on distributed computing, with trends such as "cloud" and "micro-services", this concern has never been more prevalent. Developing software which is correct and resource efficient is not an easy task at the best of times, so involving slow networks and flaky spindles of rust will not make our life easier. Software which is heavily reliant on I/O is often complex in nature, as we encounter a number of trade-offs to achieve the perfect balance of efficiency, correctness and maintainability.

Is there finally light at the end of the tunnel? Patterns are now gaining acceptance in younger languages which are gaining a broad, cross-language acceptance not often seen. This talk will take a brief look at the history of writing I/O centric software, and the techniques employed over time. By understanding these and the reason for each evolution, we can be better equipped to write, test and debug asynchronous software. Whilst C and C++ will serve as a basis for most of the talk, emphasis will also be placed on language independent concepts where appropriate.

Topics to be covered will include:

  • Why I/O is hard - the trade-offs

    • Efficiency, performance, utilisation

    • Correctness, reasoning, safety, testability

  • The baseline - blocking I/O

  • Forking and threading

  • Select and poll

  • Epoll et al - “C10K”

  • Callback based libraries (e.g. ASIO)

  • Why std::future is not the future for I/O

  • Coroutines - are we there yet?

Given time, the talk will briefly summarise techniques which have been employed in other languages, are not trivially available, or have lacked wide adoption in C/C++, such as: communicating sequential processes (Occam, Go), user-space (green) threads, task-stealing. We may discover that through all the techniques discussed, there is a lot more in common between them than is obvious at first glance.