私はtips and tricksポストで読んでいましたが、私はこれまでにやったことのないC#のものを試してみたいと思っていました。したがって、次のコードは実際の目的を果たすものではなく、何が起こるかを見るための「テスト関数」に過ぎません。あなたが見ることができるようにC#ThreadStatic + volatileメンバーが期待どおりに動作しない
private static volatile string staticVolatileTestString = "";
[ThreadStatic]
private static int threadInt = 0;
、私はThreadStaticAttributeと揮発性キーワードテストしています:
とにかく、私は2つの静的なプライベートフィールドを持っています。
とにかく、私はこのようになりますテスト方法があります。
private static string TestThreadStatic() {
// Firstly I'm creating 10 threads (DEFAULT_TEST_SIZE is 10) and starting them all with an anonymous method
List<Thread> startedThreads = new List<Thread>();
for (int i = 0; i < DEFAULT_TEST_SIZE; ++i) {
Thread t = new Thread(delegate(object o) {
// The anon method sets a newValue for threadInt and prints the new value to the volatile test string, then waits between 1 and 10 seconds, then prints the value for threadInt to the volatile test string again to confirm that no other thread has changed it
int newVal = randomNumberGenerator.Next(10, 100);
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " setting threadInt to " + newVal;
threadInt = newVal;
Thread.Sleep(randomNumberGenerator.Next(1000, 10000));
staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " finished: " + threadInt;
});
t.Start(i);
startedThreads.Add(t);
}
foreach (Thread th in startedThreads) th.Join();
return staticVolatileTestString;
}
私は、この関数から返された参照を期待したい何がこのように出力されます:
thread 0 setting threadInt to 88
thread 1 setting threadInt to 97
thread 2 setting threadInt to 11
thread 3 setting threadInt to 84
thread 4 setting threadInt to 67
thread 5 setting threadInt to 46
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
しかし、何を私はこれを取得しています:
thread 0 setting threadInt to 88
thread 4 setting threadInt to 67
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88
出力の2番目の '半分'は期待どおりの出力ですThreadStaticフィールドは私が思ったように動作していますが)、最初の出力のいくつかが最初の 'half'から 'スキップされました'ようです。
さらに、最初の '半分'のスレッドは順不同ですが、Start()を呼び出すとすぐにスレッドがすぐに実行されないことを理解しています。代わりに内部OSコントロールがスレッドが適切に見えるように開始します。
EDIT:私の脳は、だから、連続した番号
を逃すので、彼らは、実際に、私はちょうど彼らが思っていたしていないん、私の質問はありません:私は中にいくつかの行を失わせるために間違って何が起こっています最初の '半分'の出力?たとえば、 'のスレッド3の設定threadIntは84'の行はどこですか?
私はあなたのコードをいくつか実行して、いつも期待される出力を得ます... –
私はその行のどこかに賭けたいと思います。文字列の+ =は以前のスレッドがそれを設定する前に値を取得しています。新しいスレッドは新しい値で上書きします(したがって、スレッド1は出力をスキップしました)。 – Charleh
@DannyChen私はクアッドコアを利用していますが、それはアプリケーションで実行される唯一のコードではありません。それらのいずれかが意味をなさないかどうかは分かりません。もしあなたが望むなら、私はどこかでコード全体をアップロードすることができます(それは2つの.csファイルのみです)。 – Xenoprimate