multithreadingasynchronousdllsingle-threadedaddress-space

Asynchronous methods on single-threaded machine


Anatomy of a Program in Memory states that the libraries (DLLs etc.) are mapped in the Memory-mapped segment of a process. Now, when a process runs and calls the function of a library, I believe that the program counter (PC) of the thread changes to the position of function's code in the memory mapped segment and then after execution is complete, returns to the code-segment. This makes sense if the function is synchronous because we waited for the function call to complete and then moved ahead in the code segment.

Now, consider an asynchronous programming model. The library say MySql.dll is loaded in memory-mapped segment and the main code calls an asynchronous function in the dll. Asynchronous function means that PC of thread moves ahead in the code and the thread gets a call-back when the called async procedure is completed. But, in this case the async procedure is within the address space of the thread. A thread can have only one PC which begins executing the function in the DLL. Therefore, the main program in the code-segment is stalled.

This leads me to believe that async programs are no good in single-threaded systems because the program can't move ahead till the async function completes. If more than one threads were allowed, the MySql.dll could spawn a new thread (which would have its own PC) and return control to the caller in the code-segment. The PC in code-segment would proceed ahead and thus, we could see some parallelization.

I know I am wrong somewhere because async programming in very much possible in single-threaded systems (eg: JavaScript). Therefore, I wanted to identify the fallacy in my above arguments. I have following doubts. These may/may not be the source of my confusion: -

EDIT: The question above can be confusing. So, I am going to explain the main scenario here by using some notations.

A thread can have only one PC. Suppose, a single-threaded environment. Process P1 has thread T1. Say P1, refers a library L1 for an async function. L1 during loading would have been mapped to the memory-mapped segment of P1. Now, when the code in T1 calls the async function of L1, the PC (program counter) of T1 moves to the L1 segment to execute the async function. One PC can't be at two places. So, T1 doesn't proceed till async function finishes. Then, how does async benefit us in a single threaded environment?


Solution

  • "But, in this case the async procedure is within the address space of the thread"

    think what you mean by that? A procedure, both sync and async, has several pointers: program counter points to the code which is always out of address range (not space) of the thread, and stack frame and stack top pointers always belong to the address range of the thread and are used only while procedure is running.

    So from the address perspective, sync case is not different from the sync case.

    And address space always belongs to a process, and not to a library or a thread. Libraries and threads each occupy parts (ranges) of the common address space - only so they can work together.

    UPDT

    "when the code in T1 calls the async function of L1, the PC (program counter) of T1 moves to the L1 segment to execute the async function" - no, it does not. When PC moves, this is a sync call. Async call is to arrange a task which executes async procedure later. See https://en.wikipedia.org/wiki/Asynchronous_method_invocation