-1

内存中程序的剖析指出库(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 在异步函数完成之前不会继续。那么,异步如何在单线程环境中使我们受益?

4

1 回答 1

1

“但是,在这种情况下,异步过程在线程的地址空间内”

想想你的意思是什么?一个过程,无论是同步还是异步,都有几个指针:程序计数器指向的代码总是超出线程的地址范围(而不是空间),堆栈帧和堆栈顶部指针总是属于线程的地址范围和仅在程序运行时使用。

所以从地址的角度来看,sync case 和sync case 没有区别。

而且地址空间总是属于一个进程,而不是一个库或一个线程。库和线程各自占据公共地址空间的部分(范围)——只有这样它们才能一起工作。

UPDT

“当 T1 中的代码调用 L1 的异步函数时,T1 的 PC(程序计数器)移动到 L1 段以执行异步函数” - 不,它没有。当 PC 移动时,这是一个同步调用。异步调用是安排一个稍后执行异步过程的任务。请参阅https://en.wikipedia.org/wiki/Asynchronous_method_invocation

于 2017-12-24T19:20:16.340 回答