单线程机器上的异步方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单线程机器上的异步方法相关的知识,希望对你有一定的参考价值。

Anatomy of a Program in Memory声明库(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中的调用者。 code-segment的PC将继续前进,因此,我们可以看到一些并行化。

我知道我错了,因为在单线程系统中很可能进行异步编程(例如:javascript)。因此,我想确定上述论点中的谬误。我有疑虑。这些可能/可能不是我混淆的根源: -

  • 每个库是否与链接的进程共享地址空间或具有自己的地址空间?
  • 如果库有自己的地址空间,这意味着它是一个单独的进程。这是否意味着调用库中的函数和库调用回调,涉及IPC机制?

编辑:上面的问题可能会令人困惑。所以,我将通过使用一些符号来解释这里的主要场景。

一个线程只能有一台PC。假设,一个单线程环境。进程P1有线程T1。比如P1,引用库L1作为异步函数。加载期间的L1将被映射到P1的内存映射段。现在,当T1中的代码调用L1的异步功能时,T1的PC(程序计数器)移动到L1段以执行异步功能。一台PC不能在两个地方。因此,在async函数完成之前,T1不会继续。那么,async如何在单线程环境中使我们受益?

答案

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

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

因此从地址的角度来看,同步情况与同步情况没有什么不同。

地址空间始终属于进程,而不属于库或线程。库和线程各自占用公共地址空间的部分(范围) - 只有它们可以一起工作。

UPDT

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

以上是关于单线程机器上的异步方法的主要内容,如果未能解决你的问题,请参考以下文章

不同机器上的单个进程与单台机器上的多线程,核心等于单 CPU 机器的数量

Javascript的异步与单线程

node.js的单线程异步是什么意思呢?(转)

js单线程和js异步操作的几种方法

GWT 单线程异步回调

如果异步方法是单线程的,它如何在后台运行?