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

Pedro Dusso
  • 2,100
  • 9
  • 34
  • 64

3 Answers3

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.

sisve
  • 19,501
  • 3
  • 53
  • 95
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

Conrad Frix
  • 51,984
  • 12
  • 96
  • 155
0

In Windows the default stack size is 1MB.

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

Maybe, you should rethink your architecture.

GvS
  • 52,015
  • 16
  • 101
  • 139
  • 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. – sisve Dec 07 '10 at 17:44