2016-08-04 6 views
0

私は値を累積する必要があるオブジェクトのバケットを持っています。それはRwLockによって保護されているので、私はその書き込みロックを守っています。私はプロセスの持続時間の間、単一の書き込みロックを保持したい。例えば借用した変数を置換する

:私の例では、固定データを上の動作、およびそのすべてでRwLockを必要としないように見えるが

use std::sync::RwLock; 

fn main() { 
    let locked = RwLock::new(Vec::<u32>::new()); 

    // this is the entry point for real-world code 
    let mut writer = locked.write().unwrap();  

    // copy into 'locked' until it is full (has 4 items) 
    for v in 0..100 { 
     if writer.len() > 4 { 
      // discard 'writer' and 'locked', create anew 
      locked = RwLock::new(Vec::<u32>::new()); 
      writer = locked.write().unwrap(); 
     } 
     writer.push(v); 
    } 
} 

すると、実際のコードは、「実際のコード」との境界に必ずしも出口で入力します。 lockedが「フル」になっています。

借用チェッカーが不一致でなくても、必要なときに新しいlockedオブジェクトとwriterオブジェクトを作成するにはどうすればよいですか?

+0

なぜ、ベクターとその周囲のロックを破棄しなければならないのかわかりません。その中のすべてのデータを破棄するためにサイズをゼロに変更するだけではどうですか? –

+0

免責事項がありますが、私はまだあなたのプログラムを理解していません。あなたがプログラム全体の持続時間の間にライターロックを保持していれば、リーダーロックは決して得られないので、実際にはマルチスレッドの可能性はありません。 – Shepmaster

答えて

0

私は同意しますwith David GraysonRwLockを再作成する必要はありません。 Vecを切り替えるためにmem::replaceを使用し、あなたはそれを充填した後、ベクターを必要とすると仮定:

use std::sync::RwLock; 
use std::mem; 

fn main() { 
    let locked = RwLock::new(Vec::<u32>::new()); 
    let mut writer = locked.write().unwrap();  

    for v in 0..100 { 
     if writer.len() > 4 { 
      let old_vec = mem::replace(&mut *writer, Vec::new()); 
     } 
     writer.push(v); 
    } 
} 

あなたがVecを必要としない場合は、単にVec::clearを呼び出します。

+0

'mem :: replace'は、そのパラメータはソースコードで[copy_non_overlappingを使用](https://doc.rust-lang.org/std/ptr/fn.copy_nonoverlapping.html)を使用しています。私はこのコードが 'Drop'で動作するようにする必要があり、私がそれをすることが許されているのかは不明です。私はここに新しい質問を作成しました。 – njaard

+1

私はドキュメントが "クローンなし"または "ディープコピーなし"と言うべきだと思います。 'mem :: replace'は' mem :: swap'を呼び出します。これは 'mem :: forget'を正しく使って余分な落としを防ぎますので、何の問題もないはずです。とにかく、この回答のコードは 'unsafe'とは言わないので、ソースを見ていなくても余分な落としがないことを知っています:) – durka42

関連する問題