2016-08-05 2 views
4

我々はすべてTask.RunまたはParallel.ForEachのようなメソッドを知っています。 それぞれのタスクは、別々のスレッドまたはスレッドプールのスレッドのオプションに従って実行されるタスクを作成します。しかし、スタックはどこにありますか?いくつかの世代にはヒープや特別な場所がありますか?タスクスタックはC#でどこに割り当てられていますか?

たとえば、1000個のタスクを作成できます。スタックはどこにありますか? GC.Collect()を呼び出すと、ある時点で物理アドレスが移動しますか?

+2

これは、特定のCLR実装、基礎となるOS、さらにはCPUアーキテクチャに関しても非常に重要です。たとえば、Windowsでは、スレッドスタックをx86/x64メモリ管理の仕組みとインラインで割り当てる(および拡張する)ための特定のサポートがあります。 –

+0

確かに。 C#言語には、スタックがまったく存在しないという要件はほとんどありません(実際にはスタックの割り当て - C#言語仕様には 'stack'が44回しかなく、その半分は' Stack'というサンプルクラスです) –

答えて

3

スタックは、純粋に管理されていない実装の詳細です。プロセッサは何かを得るためにスタックを必要とし、それがなければ意味のあるコードを実行することはできません。これはスレッドに強く結びついています。通常のCLRホスト上の別の純粋に管理されていない詳細です。

スレッドが作成されたときにOSカーネルがそれを割り当てることを決めたメモリ内にあります。ランダムです。意図的にランダムに悪意のあるプログラムを実行すると、スタックは悪意のあるコードにデータを変換する魅力的な方法です。場所がランダムであるだけでなく、スタックが開始するスタックセグメント内の正確なオフセットもランダムです。

作成後も決して移動しません.GCはそれを変更しません。それについて知る必要があります、オブジェクトのルートはスタックに格納することができます。信頼できるスタックウォークはハードな.NET要件であり、プログラムが未処理の例外で終了したときにCLRが常に優れたスタックトレースを生成できるという基本的な理由もあります。スタック領域の不足は深刻な問題であり、プロセッサはコードを実行し続けることができません。その問題の後でプログラマのWebサイトに名前を付けるのに十分なだけです:)

2

TaskSchedulerによって実行されるデリゲートに基づいたタスクは、TaskSchedulerが使用するスタックで実行されます。デフォルトスケジューラはスレッドプールスレッドを使用します。これらは(ほとんど)通常の.NETスレッドです。

特に、Task.Runは、このようなデフォルトスケジューラベースのタスクを作成します。

TaskCompletionSourceに基づくタスクはコードを実行せず、スタックを必要としません。それらは、IO完了またはタイマーティッキングなどのいくつかの外部条件に基づいて完了します。

.NETには、ヒープベースのスタックまたは「グリーンスレッド」の組み込みサポートがありません。あなたは一般的にそのようなことを実際のコードで見つけることはできません。

関連する問題