单线程机器上的异步方法
Asynchronous methods on single-threaded machine
Anatomy of a Program in Memory 声明库(DLL 等)映射到进程的 Memory-mapped segment
中。现在,当一个进程运行并调用库的函数时,我相信线程的 program counter (PC)
会更改为函数代码在内存映射段中的位置,然后在执行完成后,return s 到 code-segment
。如果函数是同步的,这是有意义的,因为我们等待函数调用完成,然后在 code segment
.
中向前移动
现在,考虑一个异步编程模型。库 say MySql.dll 在 memory-mapped segment
中加载,主要代码调用 dll 中的异步函数。异步函数意味着线程的PC在代码中向前移动,当被调用的异步过程完成时线程得到回调。但是,在这种情况下,异步过程位于线程的地址 space 内。一个线程只能有一个 PC 开始执行 DLL 中的函数。因此,代码段中的主程序停滞了。
这让我相信异步程序在单线程系统中是不好的,因为在异步函数完成之前程序无法继续。如果允许多个线程,MySql.dll 可以产生一个新线程(它有自己的 PC)和 return 控制权给 code-segment
中的调用者。 code-segment
中的 PC 将继续进行,因此我们可以看到一些并行化。
我知道我在某个地方错了,因为异步编程在单线程系统中很有可能(例如:JavaScript)。因此,我想确定我上述论点的谬误。我有以下疑问。这些 may/may 不是我困惑的根源:-
- 是每个库都与链接进程共享地址 space 还是有自己的地址 space?
- 如果一个库有自己的地址space,那意味着它是一个独立的进程。是不是说在库中调用函数,库调用回调,涉及IPC机制?
编辑:
上面的问题可能令人困惑。因此,我将使用一些符号来解释这里的主要场景。
一个线程只能有一台PC。假设,一个单线程环境。进程 P1 有线程 T1。说 P1,为异步函数引用库 L1。加载期间的 L1 将映射到 P1 的内存映射段。现在,当T1中的代码调用L1的async函数时,T1的PC(程序计数器)移动到L1段去执行async函数。一台电脑不能在两个地方。因此,T1 在异步函数完成之前不会继续。那么,单线程环境下async对我们有什么好处呢?
"But, in this case the async procedure is within the address space of the thread"
想想你的意思?一个过程,无论是sync还是async,都有几个指针:program counter指向总是在线程地址范围之外(不是space)的代码,stack frame和stack top指针总是属于地址范围线程的并且仅在过程为 运行.
时使用
所以从地址的角度来看,sync case和sync case没有区别
而地址 space 始终属于进程,而不属于库或线程。库和线程各自占据公共地址 space 的部分(范围)——只有这样它们才能一起工作。
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" -
不,不是的。当 PC 移动时,这是一个同步呼叫。异步调用是安排一个任务,稍后执行异步过程。参见 https://en.wikipedia.org/wiki/Asynchronous_method_invocation
Anatomy of a Program in Memory 声明库(DLL 等)映射到进程的 Memory-mapped segment
中。现在,当一个进程运行并调用库的函数时,我相信线程的 program counter (PC)
会更改为函数代码在内存映射段中的位置,然后在执行完成后,return s 到 code-segment
。如果函数是同步的,这是有意义的,因为我们等待函数调用完成,然后在 code segment
.
现在,考虑一个异步编程模型。库 say MySql.dll 在 memory-mapped segment
中加载,主要代码调用 dll 中的异步函数。异步函数意味着线程的PC在代码中向前移动,当被调用的异步过程完成时线程得到回调。但是,在这种情况下,异步过程位于线程的地址 space 内。一个线程只能有一个 PC 开始执行 DLL 中的函数。因此,代码段中的主程序停滞了。
这让我相信异步程序在单线程系统中是不好的,因为在异步函数完成之前程序无法继续。如果允许多个线程,MySql.dll 可以产生一个新线程(它有自己的 PC)和 return 控制权给 code-segment
中的调用者。 code-segment
中的 PC 将继续进行,因此我们可以看到一些并行化。
我知道我在某个地方错了,因为异步编程在单线程系统中很有可能(例如:JavaScript)。因此,我想确定我上述论点的谬误。我有以下疑问。这些 may/may 不是我困惑的根源:-
- 是每个库都与链接进程共享地址 space 还是有自己的地址 space?
- 如果一个库有自己的地址space,那意味着它是一个独立的进程。是不是说在库中调用函数,库调用回调,涉及IPC机制?
编辑: 上面的问题可能令人困惑。因此,我将使用一些符号来解释这里的主要场景。
一个线程只能有一台PC。假设,一个单线程环境。进程 P1 有线程 T1。说 P1,为异步函数引用库 L1。加载期间的 L1 将映射到 P1 的内存映射段。现在,当T1中的代码调用L1的async函数时,T1的PC(程序计数器)移动到L1段去执行async函数。一台电脑不能在两个地方。因此,T1 在异步函数完成之前不会继续。那么,单线程环境下async对我们有什么好处呢?
"But, in this case the async procedure is within the address space of the thread"
想想你的意思?一个过程,无论是sync还是async,都有几个指针:program counter指向总是在线程地址范围之外(不是space)的代码,stack frame和stack top指针总是属于地址范围线程的并且仅在过程为 运行.
时使用所以从地址的角度来看,sync case和sync case没有区别
而地址 space 始终属于进程,而不属于库或线程。库和线程各自占据公共地址 space 的部分(范围)——只有这样它们才能一起工作。
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" - 不,不是的。当 PC 移动时,这是一个同步呼叫。异步调用是安排一个任务,稍后执行异步过程。参见 https://en.wikipedia.org/wiki/Asynchronous_method_invocation