24

私はThreadSchedulerタスクに関する記事を読んで学んでおり、独自の ThreadSchedulers に関するMSDN の例ThreadPool.UnsafeQueueUserWorkItemの 1 つで使用されている関数に出くわしました。UnsafeQueueUserWorkItem に関するMSDN の説明には、関数がセキュリティ ホールである可能性があり、「呼び出し元のスタックを伝達しない」という重大な警告があります。

唯一のリンクはQueueUserWorkItem、名前から見て「安全な相手」と思われるものはどれですか? スタックの呼び出しについても何も言及していません。

スタックを伝播するとは、正確にはどういう意味ですか? 作業前にコピー?とにかく、別のスレッドが呼び出しスレッドのスタックを必要とするのはなぜですか? 私は彼らが新鮮で空のスタックから始まると思います。結局、スレッド関数が戻ったときに、Task をスケジュールする関数を実行し続けませんよね?

4

1 に答える 1

30

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

この作業を行う配管は複雑で、私はそれがどのように機能するかを近似することしかできません. ExecutionContext クラスは重要であり、コードが実行されるセキュリティ コンテキストを決定します。制限された権限で実行されるスレッドが別のスレッドを開始すると、事態はさらに困難になります。明らかに、他のスレッドは元のスレッドと同じ種類の制限で実行する必要があります。CAS は、スタック ウォークを実行して制限を検出できることに依存しています。別のスレッドでは難しいです。独自のスタックがあります。

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

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

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

明らかに安全ではなく、元のスレッドの CAS 制限で実行されません。

于 2013-06-04T22:49:46.663 に答える