2010-12-07 11 views
1

私は大学での作業を行っていますが、10、100、1,000、10,000スレッドが100万回のロックとアンロックを行い、ミューテックス(static Mutex m_mutex = new Mutex();)、セマフォーがミューテックス(static SemaphoreSlim m_semaphore = new SemaphoreSlim(1);、正しい?)。C#スレッディングメモリ例外

私は、最初の3例に支障がないんだけど、私は万スレッドの場合にはメモリ例外を得ました。私のコード:

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

私は平均10回のテストを取ると仮定しています。私はこの質問を投稿している間

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

、私は再びしようとしているが、これは私がこのようなスレッドベクトル作成するには、この:

Thread[] threads = new Thread[numeroDeThreads]; 

私はミューテックスにし、ミューテックスなどセマフォでテストすることになってるし、エラーはちょうどミューテックスで起こります。

EDITでもスレッド[]スレッドと

=新しいスレッド[numeroDeThreads]。私は= OutOfMemoryException例外だ(...事前に

おかげで、

ペドロDussoが

+0

これをチェックしてくださいhttp://stackoverflow.com/questions/145312/maximum-number-of-threads-in-a-net-app – Andrey

+0

Canあなたは例外の正確なテキストを投稿しますか? –

答えて

5

10000スレッドはデフォルトのスレッドごとに1メガバイトごとに、割り当てられたスタック領域の多くの原因となります。CLRは、このメモリをコミットしますそれが利用可能でなければならず、プロセスが10000 MBのメモリを使用できるようにする必要があります。32ビットアプリケーションでは2 GB以上のプロセスメモリが割り当てられていないため、この問題が発生します。あなたにはより多くの情報があります。

0

Windowsでは、デフォルトのスタックサイズは1MBです。

1メガバイト* 10.000スレッド=単体スタックサイズの10ギガバイト

たぶん、あなたはあなたのアーキテクチャを再考する必要があります。

+0

説明:Windowsでは、10 Gbのスタックスペースを前面に使用する必要はありませんが、必要に応じてコミットします。すべてのスレッドがスタックスペースを使用している場合にのみ、10 GBが必要です。しかし、_管理されたthreads_は、作成時にスタックスペースをコミットして、10GBのメモリーを必要とします。 – sisve

1

これは、あなたがより合理的なものにジョーダフィーexplainsとしてデフォルトのスタックサイズを小さくすることができます唯一のテストですので。これを行う2つの方法は、スレッドコンストラクターを使用してサイズを制限するか、Editbinを使用することです。

以下は大体あなたがメモリ不足を実行する前に作成できるスレッドの量を四倍れる1メガバイトから256キロバイトにそれを軽減します。

EDITBIN.EXE FOO.EXE /STACK:262144

いるEDITBIN利点は、それがプールされたスレッドを含むすべてのスレッドで動作していることです。

あなたはVSコマンドプロンプトを使用している場合、これは正常に動作します。通常のコマンドプロンプトを使用する場合は、手動でdllリンクを解決する必要があります

+0

このコマンドはスタックを増やしますが、私はそれを正しく理解していますか? –

+0

このコマンドは、スレッドごとに消費されるスタックの量を、1MB –

+0

Perfectの代わりに〜256kに下げることになっています。しかし、エラー "EDITBIN:エラー:LINK.EXEを実行できません"が表示されます。私のアプリケーションはC#なので、おそらくこれは? –