2010-11-24 18 views
1

スレッドプールから取得したスレッドのプロセッサアフィニティを設定できるかどうかは疑問です。より具体的には、定期的なタスクを実装するために使用するTimerQueue APIを使用してスレッドを取得します。SetThreadAffinityプールされたスレッドのマスク

サイドノートとして:TimerQueuesは定期的なタスクを実装する最も簡単な方法ですが、これらは通常長時間の作業であるため、専用のスレッドを使用する方が適切でしょうか?さらに、セマフォやミューテックスなどの同期プリミティブを使用して、さまざまな定期的なタスクを同期させる必要があることが予測されます。プールされたスレッドはこれらに適していますか?

ありがとうございます!

EDIT1:レオが指摘したように上記の質問は、実際には2つのだけ緩く関連するものです。最初のものは、プールされたスレッドのプロセッサアフィニティに関連しています。 2番目の質問は、TimerQueue APIから取得したプールされたスレッドが、同期オブジェクトに関して手動で作成されたスレッドと同様に動作するかどうかに関連しています。私はこの第二の質問を別の話題に移します。

答えて

2

あなたがこれを行う場合、あなたは、彼らはあなたが戻ってプールにスレッドをリリースするたびにあったかに物事を返すことを確認してください。あなたはこれらのスレッドを所有していないので、それらを使用する他のコードは他の要件/前提を持つかもしれません。

は、あなたが実際にかかわらず、これを実行する必要がありますか?プロセッサアフィニティを設定する必要は非常にまれです。 (私は私が今まで私が書いたもので、それを行うために必要なてきたとは思わない。)

スレッドの親和性は、二つの全く異なるものを意味することができます。スレッドが上で一貫して実行する必要があります:私はプロセッサアフィニティを呼ぶもの(おかげでこのことを指摘して私の元の答えにコメントするのをbk1eする私は自分自身を実現していなかった。。)

  1. 同じプロセッサ。これはSetThreadAffinityMaskが扱うものであり、コードが気にすることはまれです。 (通常は、高性能なコードではCPUキャッシングのような非常に低レベルの問題が原因です。通常、OSはスレッドを同じCPUに保つために最善を尽くしますが、通常は逆効果です)。 スレッドアフィニティ:オブジェクトは、スレッドローカルストレージ(または、それらがアクセスしているスレッドに結び付けられた他の状態)を使用し、一連のアクションが同じスレッドで行われないと間違っています。

あなたの質問から#1と#2を混同しているようです。コールバックの実行中にスレッド自体がに変更されないスレッドが実行されている間は、CPU間でジャンプするかもしれませんが、それは普通のことであり、気にする必要はありません(非常に特別な場合を除いて)。スレッドがCPU間でジャンプした場合など

ミューテックス、セマフォは、気にしません。

コールバックがスレッドプールによって複数回実行される場合、(プールの使用方法によっては)通常、同じスレッドが毎回使用されることは保証されません。つまり、コールバックがスレッド間でジャンプする可能性がありますが、実行中ではありません。スレッドが再び実行されるたびにスレッドが変更されるだけです。

一部の同期オブジェクトコールバックコードが1つのスレッドで実行され、それらのオブジェクトに対するロックを保持していると考えても、別のスレッドで再度実行される場合は注意してください。 (どちらの種類の同期オブジェクトを使用するかにもかかわらず、最初のスレッドはロックを保持しますが、2番目のスレッドはロックを保持しません。これは#2であり、SetThreadAffinityMaskを使用して対処するものではありません。

例として、Mutexes(CreateMutex)はスレッドによって所有されています。スレッドAでミューテックスを取得した場合、スレッドAでミューテックスを解放するまで、ミューテックスを取得しようとする他のスレッドはブロックされます(スレッドが所有していないミューテックスを解放することもエラーです)。もしあなたのコールバックは、ミューテックスを取得し、次に終了し、別のスレッドで再度実行し、そこからミューテックスをリリースした、それは間違っています。

一方、Event(CreateEvent)は、どのスレッドがそのスレッドを作成、通知、または破棄しても気にしません。あるスレッドでイベントを通知し、別のスレッドでイベントをリセットしても問題ありません(実際は正常です)。

コールバックの2回の別々の実行の間に同期オブジェクトを保持することはまれです(デッドロックを招くことはありますが、そのようなことが正当に必要な場合もあります)。しかし、アパートスレッドのCOMオブジェクトを(たとえば)作成した場合、それは特定のスレッドからのみアクセスすることになります。

+0

マイクロソフトのドキュメントでは、「スレッドアフィニティ」を使用して、特定のスレッドのプロセッサアフィニティを参照しています。http://msdn.microsoft.com/en-us/library/ms684251%28VS.85%29.aspx – bk1e

+0

@ bk1e 、私は正しかった。それは混乱している。 :)それの音によって、OPは、単一のCPU上で一貫して実行される必要があるスレッドではなく、単一のスレッドから一貫して使用される必要のあるオブジェクトについて心配していると思います。私は私の答えを明確にします。ありがとう! –

+0

"いくつかの同期オブジェクトは気になります[...]いくつか気にしません。あなたが注意している同期化オブジェクトの例を挙げることができますか? – Arne

0

すべきではありません。あなたはその時点で実行中のプロセッサ上で、そのスレッドをただちに使用することになっています。明らかに非効率的であることを除けば、スレッドプールは完了するとすぐにすべてのスレッドを破棄し、次のジョブのために新しいスレッドを作成します。アフィニティマスクは実際にはすぐに消えませんが、ランダムに消えるとデバッグするのがさらに難しくなります。

関連する問題