2010-12-07 23 views
1

Ich mache einige College-Arbeit und ich soll 10, 100, 1.000 und 10.000 Threads simulieren 1.000.000 Sperren und entsperrt in einem Mutex (static Mutex m_mutex = new Mutex();) und in einem Semaphor als Mutex (static SemaphoreSlim m_semaphore = new SemaphoreSlim(1);, richtig ?).C# Threading Speicher Ausnahme

Ich habe keine Probleme in den ersten drei Fällen, aber ich habe eine Speicherausnahme in der 10.000 Threads Fall. Mein 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()); 

Ich soll 10 Tests nehmen und den Durchschnitt messen.

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

Während ich diese Frage posten, ich versuche wieder, aber dies das schaffe ich den Faden Vektor wie folgt aus:

Thread[] threads = new Thread[numeroDeThreads]; 

ich soll in Mutex testen und in Semaphore wie Mutex, aber der Fehler passiert im gerade Mutex.

EDIT

Auch bei den Themen [] threads = new Thread [numeroDeThreads]; Ich habe OutOfMemoryException = (...

Vielen Dank im Voraus,

Pedro Dusso

+0

überprüfen Sie diese http://stackoverflow.com/questions/145312/maximum-number-of-threads-in-a-net-app – Andrey

+0

Can Sie posten den genauen Text der Ausnahme? –

Antwort

5

10000 Threads viel zugeordnet Stapelspeicher verursacht, standardmäßig 1 Megabyte pro Thread. Die CLR wird diese einprägen erfordert, dass Ihr Prozess in der Lage ist, 10000 MB Speicher zu verwenden. 32-Bit-Anwendungen können nicht mehr als 2 GB zugeordneten Prozessspeicher haben, was dieses Verhalten verursacht.

Siehe den Blogeintrag Managed threads in "whole stack committed" shocker, der möglicherweise bereitstellen Sie mit mehr Informationen

0

In Windows ist die Standard-Stackgröße 1 MB.

1 MB * 10.000 Threads = 10 GB Stapelgröße allein.

Vielleicht sollten Sie Ihre Architektur überdenken.

+0

Klarstellung: Windows wird nicht benötigen, dass 10 GB Speicherplatz im Voraus zur Verfügung stehen, wird es aber bei Bedarf übernehmen. 10 GB werden nur benötigt, wenn alle Threads ihren Stack-Space verwenden. _Managed threads_ übergeben jedoch ihren Stack-Speicherplatz, wenn sie erstellt werden, wodurch 10 GB Arbeitsspeicher im Voraus benötigt werden. – sisve

1

Da dies nur Test ist, möchten Sie vielleicht die Standard-Stack-Größe als Joe Duffy explains auf etwas vernünftigeres zu senken. Die zwei Möglichkeiten, das zu tun, besteht darin, den Threadkonstruktor zu verwenden, um die Größe zu begrenzen, oder Sie können Editbin verwenden.

Im Folgenden wird von 1 MB auf 256 KB reduziert, was die Anzahl der Threads, die Sie erstellen können, vervierfacht, bevor Sie nicht mehr genügend Arbeitsspeicher haben.

EDITBIN.EXE FOO.EXE /STACK:262144

Der Vorteil, dass EDITBIN hat, ist, dass es für alle Threads einschließlich gepoolte Threads funktioniert.

Hinweis Dies funktioniert ordnungsgemäß, wenn Sie die VS-Eingabeaufforderung verwenden. Wenn Sie die normale Eingabeaufforderung verwenden, müssen Sie die DLL-Links manuell auflösen

+0

dieser Befehl wird den Stack erhöhen, verstehe ich es richtig? –

+0

Dieser Befehl soll die Menge des pro Thread verbrauchten Stacks auf ~ 256k statt 1MB verringern. –

+0

Perfekt, sollte funktionieren. Aber ich bekomme den Fehler "EDITBIN: Fehler: LINK.EXE kann nicht ausgeführt werden". Meine Anwendung ist C#, vielleicht weil das? –