并发线程使用相同的方法

时间:2012-10-14 06:36:56

标签: c# multithreading stack

如果我生成各种Threads,并告诉他们所有人使用相同的方法:

internal class Program {

    private static DoSomething() {

        int result = 0;
        Thread.Sleep(1000);
        result++;
        int ID = Thread.CurrentThread.ManagedThreadId;
        Console.WriteLine("Thread {0} return {1}", ID, result);
    }

    private static Main() {

        Thread[] threads = new Thread[50];

        for (int i = 0; i < 50; i++)
            threads[i] = new Thread(DoSomething);

        foreach (Thread t in threads)
            t.Start();
    }
}   

所有线程是否共享相同的堆栈?当我运行程序时,所有线程都返回1,所以我猜答案是否定的,但这是否意味着CLR在内存中制作了不同的方法副本?

3 个答案:

答案 0 :(得分:6)

  

是否意味着CLR在内存中制作了不同的方法副本?

没有。它有助于理解内存在.NET程序中的分区方式。我将跳过很多次要的实现细节来绘制大图。您可以在以下类别中细分内存:

  • 垃圾收集堆。对象存储在那里,您使用 new 运算符(结构除外)从中分配存储。它会根据需要增长,用完就会产生OutOfMemoryException。

  • 加载程序堆。 AppDomain的任何静态内容都存储在那里。很多小块但重要的是存储静态变量,类型信息(用反射检索的那种)和即时编译代码。它会根据需要增长,使用太多很难做到。

  • 堆栈。处理器的核心数据结构。不在C#中抽象它是C#生成快速程序的一个重要原因。调用方法时,堆栈存储返回地址,传递给方法的参数和方法的局部变量。默认情况下,堆栈是一兆字节,无法增长。如果您使用过多的程序,那么您的程序将失败并显示此站点的名称,因为处理器无法继续执行代码而导致严重且难以诊断失败。

一个线程看到所有这些内存类别,最后一个扭曲。每个线程都有自己的堆栈。这就是为什么它能够独立于其他线程运行自己的方法。然而,它使用与任何其他线程完全相同的代码,共享加载器堆。假设多个线程执行相同的方法。它共享相同的垃圾收集堆和静态变量。这使得编写线程代码 hard ,你必须确保线程不会踩到其他线程也使用的对象和静态变量。 lock 关键字的一个重要原因。

答案 1 :(得分:3)

不,每个线程都有自己的堆栈。而且只有一个DoSomething。每个线程都可以从任何地方访问任何类型的数据,无论是否安全,这是另一个问题。想想DoSomething,因为它只是数据,一个整数,每个线程都会增加它。现在假设DoSomething是一个函数指针,并将其地址(本质上是一个int)传递给每个线程。

答案 2 :(得分:0)

要回答你的问题,不,内存中没有多个方法副本。 只有一个副本和多个线程贯穿它。甚至是物体 内存在多个线程之间共享。这就是导致内存损坏的原因。

浏览this以更好地了解线程。

编辑: 此外,类似问题here