I'm trying to learn about coroutines, senders/receivers, async, structured concurrency, etc. within C++. I've watched cppcon talks, read online blogs, and read example code on GitHub, yet I'm still struggling to understand asynchronous computation. To simplify things, I am making this question about a single problem: opening a file asynchronously.
Why I think you should transfer files asynchronously
In my head the problem looks like this:
- There are system calls to move files between RAM and the disk. These system calls used to have two downsides: (1) they were blocking and (2) upon completion, they cause an interrupt from the DMA.
- Blocking calls and interrupts are bad because they result in a context switch, which is inefficient.
- Instead of blocking, async paradigms allow us to signal to the DMA that we want data to be moved. Moving file data to/from RAM does not require participation of the CPU, so while the DMA does its thing, our thread can continue its computation. When the DMA completes, it should (in some way) signal to our program that the file transfer is complete. Our program can then (somehow?) run a call-back function scheduled for when the file transfer completes.
The Question
Is this the kind of problem that the async paradigms exist to solve? If not, what kinds of problems are they meant to solve? If so, what is the correct way to asynchronously open a file using these new asynchronous paradigms?
My Attempt at an answer
I've been trying to answer my own question by looking at example code in CppCoro and libunifex. I can't see how the code solves the problem I have laid out. My expectation is that there should be (1) a system call for a non-blocking file transfer and (2) a way to receive a signal that the file transfer is complete so the call-back can be called. I do not see either of things. This leads me to believe that these asynchronous libraries do not exist to solve the problem I have laid out.