使ったのは、TBB バージョン3です。
#include <tbb/reader_writer_lock.h>
...
tbb:interface5::reader_writer_lock rwl;
// 書き手ロック
rwl.lock();
// アンロック
rwl.unlock();
// 読み手ロック
rwl.lock_read();
// アンロック
rwl.unlock();
というような使い方です。
サンプル・プログラムは、VC8 の MFC を使って作成しました。
縦1列がスレッドになります。上から状態を表し、
- ニュートラル
- リーダーロック初期
- リーダーロック・ロック待ち状態
- リーダーロック・ロック獲得状態
- ライターロック・ロック獲得状態
- ライターロック・ロック待ち状態
- ライターロック初期
どのクラスを使うか?の指定は、LockTestView.h で変更できます。
// BOOST read_write_mutex を利用する場合は下記をコメントアウト
// boost::thread は、ライブラリを構築する必要アリ
//#define BOOST_RW
//#define TBB_RW 1
#ifdef BOOST_RW
#include <boost/thread/shared_mutex.hpp>
#elif TBB_RW
#include <tbb/reader_writer_lock.h>
#endif
#define BOOST_RW のコメントを外せば、boost の shared_mutex を利用します。こちらの特徴は、読み手が優先だったように思います。記憶があいまいですが、リエントラント(再入可能)だったと思います。
#define TBB_RW のコメントを外せば、Intel TBB の reader_writer_lock を利用します。こちらの特徴は、書き手優先です。スピン・ロックを利用しているので、軽量なのが特徴です。たくさんの書き手が発生しない状況では、有用です。ほとんどのアプリケーションで、このクラスは活用できるのではないでしょうか?パッと見た感じ、リエントラントではありません。
何もコメントアウトしないと、私の書いたものが利用されます。Windows 限定で、ミューテックス・セマフォとゴージャスなので重量級と言えます。もちろんリエントラントではありません。特徴は、スタベーションを起こさないようにしています。
初期状態では、
// ランダムに読書をリクエストするスレッド数
#define THREAD_RANDOM_COUNT 20
// 読込みばかりをリクエストするスレッド数
#define THREAD_READONLY_COUNT 5
//#define THREAD_READONLY_COUNT 0
// 書込みばかりをリクエストするスレッド数
#define THREAD_WRITEONLY_COUNT 5
//#define THREAD_WRITEONLY_COUNT 0
かなり厳しい条件(スタベーションが起こる)ですので、
// ランダムに読書をリクエストするスレッド数
#define THREAD_RANDOM_COUNT 20
// 読込みばかりをリクエストするスレッド数
//#define THREAD_READONLY_COUNT 5
#define THREAD_READONLY_COUNT 0
// 書込みばかりをリクエストするスレッド数
//#define THREAD_WRITEONLY_COUNT 5
#define THREAD_WRITEONLY_COUNT 0
と、書き換えてテストしてみて下さい。
include, lib の設定は、自分の環境に合わせて設定しないとコンパイルできません。ソースは、MySkyDrive からどうぞ(ブログのパーツから)
0 件のコメント:
コメントを投稿