2013-06-04 14 views
13

私はThreadSchedulerとタスクについての記事を読んで学び、MSDN examplesのうちの1つで使用されている関数ThreadPool.UnsafeQueueUserWorkItemを見つけました。 MSDN description about UnsafeQueueUserWorkItemには、セキュリティホールがあり、 "は呼び出し元のスタックを伝達しません"という大きな警告があります。 "UnsafeQueueUserWorkItemと、正確に「呼び出しスタックを伝播しない」とはどういう意味ですか?

唯一のリンクはQueueUserWorkItemです - 名前から - 安全な対応者と思われますか?スタックの呼び出しについては何も言及していません。

スタックを伝播するのはどういう意味ですか?仕事が始まる前にそれをコピーしますか?とにかく別のスレッドが呼び出しスレッドのスタックを必要とするのはなぜですか?私は彼らが新鮮で空のスタックから始まると仮定します。結局のところ、スレッド関数が返ってくると、それはタスクをスケジューリングする関数を実行し続けるのではありませんか?

答えて

16

これは、CAS、Code Access Securityの実装の詳細です。スレッドが操作を実行するのに十分な権限を持っているかどうかをチェックできます。コードが完全な信頼またはサンドボックスで実行されていない、制限されたセキュリティ環境で実行される場合のみ重要です。

この作業を行う配管は複雑で、動作する方法は近似できます。 ExecutionContextクラスはキーであり、コードが実行されるセキュリティコンテキストを決定します。制限された権限で実行されているスレッドが別のスレッドを開始すると、処理が難しくなります。明らかに、他のスレッドは元のスレッドと同じ種類の制限で実行する必要があります。 CASは、スタックウォークを実行して制限を検出できるかどうかによって異なります。それは別のスレッドでは難しいです、それは独自のスタックを持っています。

ExecutionContext.Capture()メソッドは、ここで重要な役割を果たします。検出されたセキュリティ属性の「圧縮された」スタックを作成するためのスタックウォークを含む、呼び出しスレッドのコンテキストのコピーを作成します。新しいスレッドは、キャプチャされたコンテキストで実行されます。

ThreadPool.UnsafeQueueUserWorkItem()は、Capture()呼び出しをスキップします。スレッドプールスレッドは、デフォルトの実行コンテキストで実行されます。

これは最適化であり、Capture()は安価な方法ではありません。 TPスレッドに依存する種類のプログラムでは、物事を急いで行うことが重要です。 Webサーバーが気になる。また、このメソッドを使用するコードの種類は、たとえばSystem.Net名前空間の内部メソッドで使用されています。

明らかに安全ではありませんが、元のスレッドのCAS制限では動作しません。

+1

ああ、そうです。とても興味深い。今は...セキュリティ環境の下で実行されていないときに、パフォーマンスの違いはありますか? – Imi

+0

それは動作しません、CASチェックは常に実行されます。スタックウォークには、スタックの深さに依存する固定コストがあります。 「コスト」は大きな言葉ですが、ここではマイクロ秒単位の話をしています。毎秒*千のTPスレッド要求を実行するまで、これはまったく問題にはなりません。 –

+0

_マイクロソフトのほんの一言を語っています。私はここで私のカスタムスレッドスケジューラプロトタイプをプロファイルしてください。私は間違いなく "マイクロ秒"の範囲のもので生きてはいけません。 – Imi

関連する問題