内存中程序的剖析指出库(DLL 等)映射到Memory-mapped segment
进程中。现在,当一个进程运行并调用一个库的函数时,我相信program counter (PC)
线程的 会更改到函数代码在内存映射段中的位置,然后在执行完成后返回到code-segment
. 如果函数是同步的,这是有道理的,因为我们等待函数调用完成,然后在code segment
.
现在,考虑一个异步编程模型。库说 MySql.dll 已加载,memory-mapped segment
主代码调用 dll 中的异步函数。异步函数是指线程的PC在代码中向前移动,当被调用的异步过程完成时线程得到回调。但是,在这种情况下,异步过程位于线程的地址空间内。一个线程只能有一台 PC 开始执行 DLL 中的函数。因此,代码段中的主程序被停止。
这使我相信异步程序在单线程系统中不好用,因为在异步函数完成之前程序无法继续前进。如果允许多个线程,则 MySql.dll 可以生成一个新线程(它将拥有自己的 PC)并将控制权返回给code-segment
. PC incode-segment
将继续进行,因此我们可以看到一些并行化。
我知道我在某个地方错了,因为在单线程系统(例如:JavaScript)中很可能进行异步编程。因此,我想找出我上述论点中的谬误。我有以下疑问。这些可能/可能不是我困惑的根源:-
- 每个库是否与链接进程共享地址空间或拥有自己的地址空间?
- 如果库有自己的地址空间,这意味着它是一个单独的进程。这是否意味着调用库中的函数和调用库的回调,涉及IPC机制?
编辑: 上面的问题可能令人困惑。所以,我将通过使用一些符号来解释这里的主要场景。
一个线程只能有一台 PC。假设,一个单线程环境。进程 P1 有线程 T1。说 P1,指的是用于异步函数的库 L1。加载期间的 L1 将被映射到 P1 的内存映射段。现在,当 T1 中的代码调用 L1 的 async 函数时,T1 的 PC(程序计数器)移动到 L1 段以执行 async 函数。一台电脑不能在两个地方。因此,T1 在异步函数完成之前不会继续。那么,异步如何在单线程环境中使我们受益?