2

I'm doing some college work and I'm supposed to simulate 10, 100, 1,000 and 10,000 threads doing 1,000,000 locks and unlocks in a mutex (static Mutex m_mutex = new Mutex();) and in a semaphore as mutex (static SemaphoreSlim m_semaphore = new SemaphoreSlim(1);, correct?).

I'm having no trouble in the first three cases, but I got a Memory Exception in the 10,000 threads case. My code:

        resultados.WriteLine("=== 10 threads ===");
        ts = new TimeSpan();
        media = 0;
        parcial = 0;
        resultados.WriteLine("Parciais:");
        for (int i = 0; i < 10; i++)
        {
            parcial = LockAndUnlock_Semaphore_ComDisputa(10);
            media += parcial;
            ts = TimeSpan.FromTicks(parcial);
            resultados.WriteLine(ts.ToString());
        }
        ts = TimeSpan.FromTicks(media / 10);
        resultados.WriteLine("Média: " + ts.ToString());

I'm supposed to take 10 tests and measure the average.

private static long LockAndUnlock_Semaphore_ComDisputa(int numeroDeThreads)
    {
        Thread[] threads10 = new Thread[10];
        Thread[] threads100 = new Thread[100];
        Thread[] threads1000 = new Thread[1000];
        Thread[] threads10000 = new Thread[10000];
//switch in the numeroDeThreads var
//[...]
 case 10000:
 sw.Start();
 for (int i = 0; i < numeroDeThreads; i++)
 {
      threads10000[i] = new Thread(LockUnlockSemaphore);
      threads10000[i].Priority = ThreadPriority.Highest;
      threads10000[i].Start();
 }
 for (int i = 0; i < numeroDeThreads; i++)
 {
      threads10000[i].Join();
 }
 sw.Stop();
 break;
//[...]
return sw.ElapsedTicks;


 static void LockUnlockSemaphore()
    {
        for (int i = 0; i < 1000000; i++)
        {
            m_semaphore.Wait();
            //thread dentro do semaforo
            m_semaphore.Release();
        }
    }

While I post this question, I'm trying again but this this I create the thread vector like this:

Thread[] threads = new Thread[numeroDeThreads];

I'm supposed to test in mutex and in semaphore as mutex, but the error happen in the just mutex.

EDIT

Even with the Thread[] threads = new Thread[numeroDeThreads]; I got outofmemoryexception =( ...

Thanks in advance,

Pedro Dusso

2

3 Answers 3

6

10000 threads will cause a lot of allocated stack space, per default 1 megabyte per thread. The CLR will commit this memory requiring it to be available, requiring your process to be able to use 10000 mb of memory. 32 bit applications are unable to have more than 2 gb mapped process memory, causing this behavior.

See the blog entry Managed threads in "whole stack committed" shocker which may provide you with more information.

Sign up to request clarification or add additional context in comments.

Comments

1

Since this is only test you might want to lower the default stack size as Joe Duffy explains to something more reasonable. The two ways to do this is to use the thread constructor to limit the size or you can use Editbin.

The below reduces it from 1MB to 256KB which will roughly quadruples the amount of threads you can create before you run out of memory.

EDITBIN.EXE FOO.EXE /STACK:262144

The advantage that editbin has, is that it works for all threads including pooled threads.

Note this will work correctly if you use the VS command prompt. If you use the normal command prompt you will need to resolve the dll links manually

6 Comments

this command will increase the stack, am I understand it right?
This command is supposed to lower the amount of stack consumed per thread to ~256k instead of 1MB
Perfect, should work. But I get the error "EDITBIN :error : cannot execute LINK.EXE". My application is C#, maybe because this?
It works fine for C# for me, but only when I run it from the Visual Studio command prompt
I think this will work for me in C# msdn.microsoft.com/en-us/library/5cykbwz4.aspx
|
0

In Windows the default stack size is 1MB.

1MB * 10.000 threads = 10GB of stack size alone.

Maybe, you should rethink your architecture.

1 Comment

Clarification: Windows wont require that 10 gb stack space to be available up front, but will commit it when necessary. 10 gb is only needed if all threads are using their stack space. Managed threads, however, commit their stack space when created causing the need for 10 gb memory up front.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.