2016-07-11 1 views
1

は、forループのインデックスiが正しくループをマルチスレッド化された方法DoWork_Threaded()C#でのスレッディング:ループインデックスをスレッドセーフにするには?次の例では

に(さえSystem.Environment.ProcessorCount-1より大きい値、倍数)iの奇妙な値に至る各スレッドによって独立して修飾されると思われますCで行われた#?

// Prepare all threads 
Thread[] threads = new Thread[System.Environment.ProcessorCount]; 

// Start all threads 
for (int i = 0; i < System.Environment.ProcessorCount; i++) 
{ 
    threads[i] = new Thread(() => DoWork_Threaded(i)); 
    threads[i].Start(); 
} 

// Wait for completion of all threads 
for (int i = 0; i < System.Environment.ProcessorCount; i++) 
{ 
    threads[i].Join(); 
} 
+0

回答ありがとうございますが、これはインデックスiでどのように役立ちますか? PS:それはまた働いていません。 –

+0

ループ内の値をコピーしようとしました 'int a = i;' DoWork_Threaded(a); – user3185569

+2

コードがどのように振舞うのかについては、https://blogs.msdn.microsoft.com/を参照してください。 ericlippert/2009/11/12/closed-over-the-loop-variable-considered-有害な/。スレッド化とはまったく無関係です。ループ変数をクロージャーすると、記述した動作が発生する可能性があります。 – Dirk

答えて

5

まず、スレッドスケジューリングサービスをローリングするのではなく、なぜタスク並列ライブラリを使用しないのですか?すでにスレッドをスケジュールするプロセッサの数を決定するロジックを持っています。

実際の質問にお答えするには、ループ変数でを締めてください。それは間違っている理由について私の記事を参照してください。

要するに

https://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

i変数と変数変更です。ラムダが実行されると、の現在のの値がiで実行されます。デリゲートが作成されたときの値ではありません。

+0

かなりいいTPLに私を指摘してくれてありがとう。しかし、私の場合は、すべてのコアに手動で処理された数百万のイメージピクセルがあります。これはParallel.Forを使用するのと比べてエラーが発生しやすいようですが、それはずっと高速です。私はParallel.Forがどのように作品を配布しているのか分かりませんが、これはもっと多くのスレッドを作成するオーバーヘッドが原因だと思います。 –

+0

このような場合(Parallel.Forループの何百万もの要素)のTPLに(第4四半期の例では)第1四半期にコア1、第2四半期にコア2などを使用する方法がありますか? –

+0

@ares_games:これはQ&Aサイトです。ゲームサイトで、ここで、あるいはそれ以上に投稿するのはいい質問のようです。 –

3

匿名のメソッドとスレッドでローカル変数を使用するのは難しい場合があります。

for (int i = 0; i < System.Environment.ProcessorCount; i++) 
{ 
    int a = i; 
    threads[i] = new Thread(() => DoWork_Threaded(a)); 
    threads[i].Start(); 
} 

これは私のマシン上で合理的な出力になります:あなたはそれが変化しているとして匿名メソッドによって使用されている値をコピーする必要があります。

関連する問題