gpt4 book ai didi

language-agnostic - 当一种方法调用另一种方法时,幕后会发生什么?

转载 作者:行者123 更新时间:2023-12-03 18:24:47 25 4
gpt4 key购买 nike

这类似于 What happens when you run a program? ,但不是骗子。

假设我有一个简单的控制台程序,有两种方法 A 和 B。

    public static void RunSnippet()
{
TestClass t = new TestClass();
t.A(1, 2);

t.B(3, 4);
}

public class TestClass
{
public void A(int param1, int param2)
{
//do something
C();
}

private void C()
{
//do
}

public bool B(int param1, int param2)
{
//do something
bool result = true;

return result;
}
}

有人可以详细解释一下(但请用简单的英语),当 RunSnippet 调用方法 A 和方法 B(并且它们在内部调用其他一些方法)时真正发生了什么。我想了解幕后真正发生的事情......意味着参数如何传递,它们存储在哪里,本地变量会发生什么,返回值如何传递,如果另一个线程在 A 调用 C 时开始运行会发生什么,如果抛出异常会发生什么。

最佳答案

我不太确定您正在寻找什么级别的详细信息,但这是我解释正在发生的事情的尝试:

  • 为您的可执行文件创建了一个新进程。该进程有一个包含每个线程堆栈的堆栈段、一个用于静态变量的数据段以及一个用于动态分配内存的称为堆的内存块,以及一个包含已编译代码的代码段。
  • 您的代码被加载到代码段中,指令指针设置为 main() 方法中的第一条指令,然后代码开始执行。
  • 对象 t 从堆中分配。 t 的地址存储在堆栈中(每个线程都有自己的堆栈)。
  • 通过将 main() 的返回地址放在堆栈上并将指令指针更改为 t.A() 代码的开头来调用 t.A()。返回地址与值 1 和 2 一起放置在堆栈中。
  • t.A() 通过将 t.A() 的返回地址放在堆栈上并将指令指针更改为 t.C() 代码的起始地址来调用 t.C()。
  • t.C() 通过从堆栈中弹出 t.A() 的返回地址并将指令指针设置为该值来返回。
  • t.A() 以与 t.C() 类似的方式返回。
  • 对 t.B() 的调用与对 t.A() 的调用非常相似,只是它返回一个值。返回该值的确切机制取决于语言和平台。通常,该值将在 CPU 寄存器中返回。

  • 注意:由于您的方法非常小,现代编译器通常会“内联”它们,而不是进行经典调用。内联意味着从方法中获取代码并将它们直接注入(inject)到 main() 方法中,而不是通过进行函数调用的(少量)开销。

    鉴于您的示例,我看不到线程如何直接进入图片。如果您要再次启动可执行文件,它将在新进程中运行。这意味着它将获得自己的代码段、数据段和堆栈段,将其与第一个进程完全隔离。

    如果您的代码在一个在多个线程上调用 main() 的较大程序中运行,它将几乎完全按照前面描述的方式运行。该代码是线程安全的,因为它不访问任何潜在的共享资源,例如静态变量。线程 1 无法“看到”线程 2,因为所有关键数据(值和指向对象的指针)都存储在线程的本地堆栈中。

    关于language-agnostic - 当一种方法调用另一种方法时,幕后会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1285244/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com