アップグレード/ダウングレード

アップグレード/ダウングレード#

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 メソッドがありますが、実際に使用するケースはほとんどありません。