Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用相同方法的并发线程_C#_Multithreading_Stack - Fatal编程技术网

C# 使用相同方法的并发线程

C# 使用相同方法的并发线程,c#,multithreading,stack,C#,Multithreading,Stack,如果我生成各种线程,并告诉它们使用相同的方法: internal class Program { private static DoSomething() { int result = 0; Thread.Sleep(1000); result++; int ID = Thread.CurrentThread.ManagedThreadId; Console.WriteLine("Thread {0} r

如果我生成各种线程,并告诉它们使用相同的方法:

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();
    }
}   
内部类程序{
专用静态剂量仪(){
int结果=0;
睡眠(1000);
结果++;
int ID=Thread.CurrentThread.ManagedThreadId;
WriteLine(“线程{0}返回{1}”,ID,result);
}
私有静态Main(){
线程[]线程=新线程[50];
对于(int i=0;i<50;i++)
线程[i]=新线程(DoSomething);
foreach(螺纹中的螺纹t)
t、 Start();
}
}   

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

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

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

仔细阅读,更好地理解线程

编辑: 还有,类似的问题

这是否意味着CLR会在内存中创建该方法的不同副本

不是。它有助于理解.NET程序中内存是如何分区的。我将跳过许多次要的实现细节来勾勒全局。您可以将内存细分为以下类别:

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

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

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


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

非常感谢,这非常有帮助!