C++ Boost

Boost.Threads

Overview


はじめに
注意事項
テストとデバッグに関する考察
予備知識
マルチスレッドにおける標準ライブラリの利用
ランタイムライブラリ
潜在的なスレッドセーフでない関数
コンポーネントの共通概念
例外
NonCopyable 要求

はじめに

複数のスレッドを使って並列に動作するプログラムは、伝統的なシングルスレッドプログラムに対してマルチスレッドプログラムと呼ばれている。
Boost.Threads ではC++プログラムにおける多重で非同期な独立した実行単位別のスレッド(クラス)を提供してマルチスレッドプログラムをサポートしている。
(もちろん)それぞれのスレッドには、CPUの命令カウンタやレジスタ情報を含む、独自のマシンステートを持たせている。

Definitions の項ではマルチスレッド開発における実行環境についてさらに詳しく解説している。

マルチスレッド開発には次のような利点がある:

注意事項

シングルスレッドプログラムにおいて発生しうるエラーに加え、マルチスレッドプログラムでは次のような問題を考慮する必要がある。

すべてのマルチスレッドプログラムは、レースコンディション、デッドロックおよび優先順位問題などを回避できるように注意深く設計されていなければならない。
これらの諸問題は珍しいものでも風変わりなものでもなく、マルチスレッドのプログラムコードがそれらを回避できるように設計されていない限り当然起こりうるものである。
「優先順位問題」に関してはあまり一般的ではないが、しかし十分深刻な問題である。

Boost.Threads の設計では、これらのエラーを最小限にしようと試みている。
しかし、それを利用するプログラマがその問題を回避するつもりでない限り発生を抑止できるものではないことを念頭に置くべきである。

テストとデバッグに関する考察

マルチスレッドプログラムは確固たる手順を踏んで実行されるわけではない。同じプログラムに対して同じ入力があったとしてもそれが行使されるタイミングによっては異なる実行パスをたどるかも知れないのだ。
そして、このことがテストとデバッグに次のような悪夢のごとき結果を招くことにつながってくる:

予備知識

マルチスレッドのプログラムはあてにならないと思われるかも知れないが、実際には多くの信頼できるマルチスレッドプログラムが存在している。
マルチスレッド開発技術がプログラムの信頼性を高めることは周知の事実なのだ。

信頼できるマルチスレッドプログラムのためのデザインパターン(最も重要なモニタパターンを含む)がPattern-Oriented Software Architecture Volume 2 - Patterns for Concurrent and Networked Objects に紹介されている。[Schmidt 00]
Programming with POSIX Threads [Butenhof 97] では、マルチスレッドプログラミングにおける多くの重要な考察が議論されている。

マルチスレッドの設計を試す前に多少なりとも関連書籍を読んでおけば、より信頼できるマルチスレッドプログラムを生み出せるようになるだろうことは言うまでもない。

マルチスレッドにおける標準ライブラリの利用

ランタイムライブラリ

警告:Boost.Threads を使うようなマルチスレッドプログラム全般においては、C++の標準ライブラリはもちろんのこと、すべてにおいてスレッドセーフなランタイムライブラリをリンクしなければならない。
new や delete あるいは『その他の言語』などの共有された状態を持つランタイムライブラリの関数が複数のスレッドから同時に実行されるとレースコンディション[以外の問題?]が発生しうることになる。

潜在的なスレッドセーフでない関数:

C言語から受け継がれてきたC++の標準ライブラリの一部の関数は、関数コール間に内部でその状態を保持するという特別な問題を潜在させている。

スレッド固有ストレージ』(thread-specific storage)を使用することでこれらの関数のスレッドセーフな実装は可能であり、一部のコンパイラベンダによって既に提供されてもいる。
[Buttenhof 97]で解説されているテクニックはよく知られている。

いまだにHP−UXはこのスレッドセーフなランタイムライブラリを実装していないが、その代わりに異なる名前の代替関数が用意されている。

『推薦:』手っ取り早くこれらの関数群をスレッドセーフにするのに Boost を使うという方法もある。
[Boost Random Number Library]と[Boost Tokenizer Library]を参照。

Boost.Threads コンポーネントの共通概念

例外

Boost.Threads はデストラクタで例外を投げることはない。
特に指定されない限り(デストラクタ以外の例外に関する指定を持たない)Boost.Threads の関数は、実装上定義された例外を投げることがある。

記憶領域割り当てに失敗した場合には std:bad_alloc あるいは std::bad_alloc 派生クラスを、メモリ以外のスレッドリソースの獲得に関する例外では boost::thread_resource_error を、ロックメカニズムに関わる失敗に関しては boost::lock_error 例外をそれぞれ通知してくる点は重要である。

『基本事項:』デストラクタあるいは特定の関数を除くすべての関数はC++標準ライブラリの実装に基づいてエラー時の例外を投げる。

NonCopyable 要求

Boost.Threads のNonCopyable 要求として記載されているクラスでは、コピーコンストラクタとコピー代入が許可されない。
これを明示的にするためには、そのようなクラスを boost::noncopyable からプライベートに派生させるといい。
NonCopyable な要求は、他の方法で自由にインプリメントできるので、この派生に依存しすぎてはいけない。


Revised 09 January, 2003

© Copyright William E. Kempf 2001-2002. All Rights Reserved.

Japanese Translation Copyright (C) 2003 by you-chi@fsinet.or.jp.

オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の 複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」 に提供されており、いかなる明示的、暗黙的保証も行わない。また、 いかなる目的に対しても、その利用が適していることを関知しない。