InfoQ

News

データ構造の調整:.NETマルチスレッド化の新たなクラス

作者 Jonathan Allen, 翻訳者 編集部 投稿日 2008年6月13日 午後12時35分

コミュニティ
.NET
トピック
パフォーマンス&スケーラビリティ
タグ
Parallel Programming

6月のParallel Extensions for .NET(source)のリリースにより、一連のクラスが追加され、マルチスレッドアプリケーションにおけるデータの共有がますます容易になった。新たな同期プリミティ ブ、機能およびコレクションクラスを含む10の新たなクラスに関して、それぞれについて簡単に触れることとするが、これが最初で最後である。

クラスの最初のバッチは、System.Threading名前空間にある。

CountdownEventが無限数のスレッド間の調整を可能にする。各スレッドが開始すると、カウンターはプリセットされるかインクリメントする。スレッドがタスクを完了すると、カウンターをデクリメントする。カウンターがゼロになるまで、CountdownEvent.Waitへの呼び出しによりメインスレッドはブロックされる。この意味では、CountdownEventAutoResetEventおよびManualResetEventと似ている。

基本的にLazyInitは、Futureと呼ばれているものである。LazyInitオブジェクトは、クラスや代行を受け取る。クラスを受け取ると、Valueプロパティが呼び出されたとき、デフォルトのコンストラクターで新しいインスタンスを作成する。代行が指定されると、代行の結果が格納されて、返される。

LazyInitには値の作成モードが3種類ある。AllowMultipleExecutionによって、各スレッドが最初に値を初期化しようとするが、必ず1つのオブジェクトのみが返される。その結果、複数のオブジェクトが作成されて、破棄されることにつながりかねない。EnsureSingleExecutionは、確実に1つのインスタンスのみが作成されるようにしている。最終的にThreadLocalは、各スレッドに別々のインスタンスを提供する。

WriteOnceは、LazyInitに替わるものと見ることができる。LazyInitのように、その値は一度のみ設定可能であり、その後は不変である。しかしながら、WriteOnceの値は外部からクラスへ割り当てられる。いったん設定されると、決して変わらない。

読み取り専用のセマンティクスが必要な場合、WriteOnceは特に便利である。しかしコンストラクターに値を割り当てる必要がないので、読み取り専用の修飾子を使用することはできない。 WriteOnceオブジェクトに複数回値を割り当てようとすると「破損」と表示され、二度と読み取りができなくなる。 Valueプロパティの代わりにTrySetValueを使用することで、この破損を防止することができる。

ManualResetEventSlimManualResetEventの軽バージョンである。旧バージョンと違い、カーネルオブジェクトに依存せず、終了化可能ではない。頻繁に作成される場合には、パフォーマンスの向上につながる。

ManualResetEventSlimのように、SemaphoreSlimはカーネルのシンラッパーを軽量のものと置き替える。

 

SpinLockおよびSpinWaitのさらに2つの軽量オブジェクトは、マルチコアおよびマルチプロセッサマシンに実に最適である。 両者共にブロック化スレッドをアクティブにし、本質的にCPUサイクルを浪費する。予想待機時間が非常に短く、コンテキストスイッチが障害になっている場合は便利である。

クラスの2番目のグループは、System.Threading.Collections名前空間にある。

ConcurrentQueueはマルチスレッドを考慮したキュー構造である。古いキュー、「スレッドセーフ」がロックを必要とする場合でさえ、Countプロパティを確認しアトミックアクションとしてDequeueを呼び出すことができる。ConcurrentQueueは、 TryDequeueメソッドを提供することのみによって、その落とし穴を避ける。数を確認せずに呼び出しても安全なので、明示的なロックを必要としない。

スタックセマンティクスでConcurrentStackは同様の動作をする。

複数の読み取りプログラムや書き出しプログラム向けに設計されたBlockingCollectionは、たいていは別々に実装する機能が多く装備されているため、やや複雑である。まず最初に、BlockingCollectionはコレクションとして単独で使用できる。またConcurrentStackConcurrentQueueのようなIConcurrentCollectionオブジェクトを折り返させることで、セマンティクスは変化する。

たいていのコレクションとは違い、BlockingCollectionGetConsumingEnumerableと いうメソッドのようなものをサポートする。これにより、コレクションに対してfor-eachループやLINQクエリーをスレッドセーフな方法で使用する ことができる。通常は、キューからアイテムを消費するような破壊的な操作は、どちらかの構造を使用している場合、例外を引き起こす。

書き出しプログラムを停止するには、BlockingCollectionsにサイズの上限を指定する。この限界を超えると、コレクションに追加する呼び出しがブロックされる。

BlockingCollectionsにも「コンプリート」しているという概念がある。CompleteAddingを呼び出す場合、コレクションには新たな項目は追加されないこと、および現在のバッチ終了後に処理を停止することができることが通知される。

最後に、BlockingCollectionsはグループでも使用可能である。オブジェクトをBlockingCollectionsの配列とともにAddAny?に渡す場合、オブジェクトはそのうちのどれか1つに付加される。ドキュメンテーションはまだ貧弱であるが、おそらくそれにより選択されたコレクションが最小である。すべてのコレクションがフルの場合、この呼び出しはブロックしている。

原文はこちらです:     http://www.infoq.com/news/2008/06/CDS

ブックマーク
digg+,
reddit+,
del.icio.us+,
dzone+,
Hatena

No comments

返信

特集コンテンツ一覧

トップスポーツチームの監督に教わる秘訣

この論文では、氏が発見した原則を要約し、その原則をいかにしてソフトウェア開発に応用するかを説明します。

事例研究:Dutch Railwaysのプロジェクトにおける分散拠点でのスクラム・プロジェクト

この記事では、私達がどのようにして大規模(240人月、10万行強)でインドとオランダの開発者も参加したスクラム・プロジェクトを成功させたのかを示しています。

Agile2008チーム参加レポート - 帰国そして変化

Agileカンファレンスに「参加者としてだけでなく、発表者として参加しよう」を掲げたチームgoyattomは、サブミッションを提出し、7つのセッションが日本から選択されました。参加者はカンファレンスで各々の発表や、各セッションへの参加、諸外国のエンジニアとの出会い、ステージ上で DearXPを熱演などの様々な思い出を抱えて、無事日本に戻ってきました。

SilverlightとJavaのインターオペラビリティ

マイクロソフトのRobert Bellが、SilverlightとJavaを使用したインターオペラビリティのシナリオを紹介し、サンプルコードを例にとってアーキテクチャの手引きを提供します。

Agile2008 チーム参加レポート - カンファレンス参加編

Agileカンファレンスに「参加者としてだけでなく、発表者として参加しよう」を掲げたチームgoyattomは、サブミッションを提出し、7つのセッションが日本から選択されました。サブミッションが選択された人、そうでない人も含めて、個々の目的意識の確認、膨大なプログラムから聞きたいセッションの選択、旅行の準備、プレゼンテーションの準備の期間を終えて、無事当日を迎えました。

Agile2008 チーム参加レポート - 動機/準備編

筆者はアジャイルソフトウェア開発についての年に一度の国際会議であるAgile2008に初めて参加してきました。今年の日本からの参加者の数は14名にも及び、発表者は5名、受け持ったセッションは8つに及び、例年にない活躍を見せました。なぜ今年のAgile2008では、これほど多くの日本人が参加し発表に至ったのか? そのレポートをお届けします。

Javaトラブルシューティングメルマガ総集編 2008/08~09

エスエムジーでは、Java全般を対象にしたトラブルシューティングサービス「JaTS」を提供しています。この記事では、前回に引き続き、JaTSにて蓄積したトラブル事例とその解決ノウハウの一部をお送りしている「Javaトラブルシューティングメールマガジン」(JTSMM)の総集編として、過去2ヶ月のトラブル事例と追加情報をダイジェストとして提供いたします。

モデル駆動アプローチがうまく機能しない(しなくなる)8 つの理由

この記事では、モデル駆動アプローチがうまく機能しない、または機能しなくなることによって期待した結果が実現できなくなる 8 つの理由について書きたいと思います。