iostream ライブラリでは、iostream オブジェクトに対する一連の操作をロックするための stream_locker クラスが提供されています。したがって、iostream のロックとロック解除を動的に設定することによるオーバーヘッドを最小にすることができます。
stream_locker クラスのオブジェクトを使用すると、ストリームオブジェクトに対する一連の操作を不可分命令的に実行することができます。たとえば、次の例では、ファイル内の位置を指定して、そこからデータを 1 ブロック読み込みます。
#include <fstream.h> #include <rlocks.h> void lock_example (fstream& fs) { const int len = 128; char buf[len]; int offset = 48; stream_locker s_lock(fs, stream_locker::lock_now); . . . . .// ファイルをオープン fs.seekg(offset, ios::beg); fs.read(buf, len); }
この例では、stream_locker オブジェクトのコンストラクタが相互排他制御域の開始を定義します。相互排他制御域では、一度に 1 つのスレッドしか実行されません。また、関数から戻った後で呼び出されるデストラクタでは、相互排他制御域の終了を定義します。したがって、stream_locker オブジェクトにより、ファイル内の特定の位置のシークと、ファイルからのデータの読み込みとが不可分命令的に実行されます。スレッド A がファイルからデータを読み込む前に、スレッド B がファイル内の位置を変えてしまうことができなくなるためです。
stream_locker オブジェクトのもう 1 つの使用方法として、相互排他制御域を明示的に定義する方法があります。次の例では、入出力操作とそれに続くエラー検査を不可分命令的に実行するため、stream_locker オブジェクトのメンバー関数 lock と unlock を呼び出します。
{ ... stream_locker file_lck(openfile_stream, stream_locker::lock_defer); .... file_lck.lock(); // openfile_stream をロック openfile_stream << "Value: " << int_value << "¥n"; if(!openfile_stream) { file_error("Output of value failed¥n"); return; } file_lck.unlock(); // openfile_stream のロックを解除 }
stream_locker についての詳細は、stream_locker(3) のマニュアルページを参照してください。