3

If I spawn various Threads, and tell them all to use the same method:

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();
    }
}   

Will all the Threads share the same stack? When I run the program all Threads return 1, so I guess the answer is no, but then does that mean that the CLR makes different copies of the method in memory?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Bruno Santos
  • 724
  • 7
  • 19

3 Answers3

6

does that mean that the CLR makes different copies of the method in memory?

No. It helps to understand how memory is partitioned in a .NET program. I'll skip a lot of minor implementation details to draw the Big Picture. You can subdivide memory in these categories:

  • The garbage collected heap. Objects are stored there, you allocate storage from it with the new operator (except structs). It grows as needed, running out of it produces an OutOfMemoryException.

  • The loader heap. Anything that's static for an AppDomain is stored there. Lots of little pieces but the important ones are storage for static variables, type information (the kind you retrieve with reflection) and just-in-time compiled code. It grows as needed, using too much of it is very hard to do.

  • The stack. A core data structure for the processor. Not abstracting it away in C# is an important reason that C# produces fast programs. The stack stores the return address when you call a method, the arguments passed to a method and local variables of a method. By default a stack is one megabyte and cannot grow. Your program fails with this site's name if you use too much of it, a gross and hard to diagnose failure because the processor cannot continue executing code.

A thread sees all these memory categories, with a twist on the last one. Every thread has its own stack. Which is above all why it is capable of running its own methods, independent of other threads. It however uses the exact same code as any other thread, the loader heap is shared. Assuming more than one thread executes the same method. And it shares the same garbage collected heap and static variables. Which makes writing threaded code hard, you have to ensure that threads don't step on objects and static variables that are also used by other threads. An important reason for the lock keyword.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
3

No, each thread has its own stack. And there's just one DoSomething. And each thread can access any sort of data from anywhere, whether safely that's another question. Think of DoSomething as it were just data, an integer, and each thread increments it. Now imagine that DoSomething is a function pointer, and you pass its address (an int, essentially) to each of the threads.

0

To answer your question, no, there aren't multiple copies of the method in memory. There is just one copy and multiple threads that run through it. Even the objects in memory are shared between multiple threads. That is what leads to memory corruption.

Go through this to understand about threads a bit better.

Edit: Also, similar question here.

Community
  • 1
  • 1
Aniket
  • 1,308
  • 1
  • 11
  • 13