Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent Threads using same method

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?

like image 928
Bruno Santos Avatar asked Dec 19 '25 00:12

Bruno Santos


2 Answers

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.

like image 57
Hans Passant Avatar answered Dec 20 '25 13:12

Hans Passant


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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!