アップグレード/ダウングレード#
upgrade_to_writer メソッドを使用して、リーダーロックをライターロックにアップグレードできます。次に例を示します。
std::vector<string> MyVector;
typedef spin_rw_mutex MyVectorMutexType;
MyVectorMutexType MyVectorMutex;
void AddKeyIfMissing( const string& key ) {
// MyVectorMutex のリーダーロックを取得
MyVectorMutexType::scoped_lock lock(MyVectorMutex,/*is_writer=*/false);
size_t n = MyVector.size();
for( size_t i=0; i<n; ++i )
if( MyVector[i]==key ) return;
if( !lock.upgrade_to_writer() )
// ロックが一時的に解除されている間にキーが追加されたかどうかを確認
for( int i=n; i<MyVector.size(); ++i )
if(MyVector[i]==key ) return;
vector.push_back(key);
}ベクトルを再度検索する場合があることに注意してください。これは、upgrade_to_writer が、アップブレードの前に一時的にロックを解放する可能性があるためです。そうしないと、ロックの病理で説明されているように、デッドロックが発生する可能性があります。メソッド upgrade_to_writer は、ロックを解除せずにアップグレードされた場合は true を返し、ロックが一時的に解除された場合は false を返します。そのため、upgrade_to_writer で false が返された場合、コードは検索を再実行して、キーが別のライターによって挿入されていないことを確認する必要があります。この例では、キーは常にベクトルの末端に追加され、キーは削除されないことを前提としています。このような想定により、ベクトル全体の検索をやり直す必要はなく、最初に検索された範囲以外の要素のみを検索できます。重要な点は、upgrade_to_writer が false を返したとき、リーダーロックを保持している間に確立されたすべての仮定は無効になり、再確認が必要であることです。
対称性については、対応する downgrade_to_reader メソッドがありますが、実際に使用するケースはほとんどありません。