extern crate / use
#[macro_use]
extern crate lazy_static;
use std::sync::RwLock;
グローバル変数の宣言
lazy_static! {
static ref Str_g: RwLock<String> = RwLock::new("hoge".to_string());
static ref Int_g: RwLock<i32> = RwLock::new(0);
}
メソッド
read()
グローバル変数のポインタをread-onlyで取得します。
let str_g = Str_g.read().unwrap();
println!("{}", *str_g);
write()
グローバル変数のポインタをrwで取得します。
let str_g = Str_g.write().unwrap();
*str_g = "fuga";
println!("{}", *str_g);
try_read() / try_write()
上記の二つは、グローバル変数をロックするとスレッドをブロックします。
しかし、try_read() / try_write()はブロックしません(ロックはします)。
しかし、他のスレッドでロックされていた場合、ロックに失敗し、パニックします。
read() / write()はロックを獲得できるまで、待機し続けます。
let str_g = Str_g.try_read().unwrap();
let str_g = Str_g.try_write().unwrap();
注意点
ポイズニング
writeロックを獲得しているスレッドがパニックになった時、ロックで守られているデータの整合性が保たれているか保証できなくなるため、ロックを獲得できなくなります。
デッドロック
既にロックを獲得しているグローバル変数をロックしようとすると、デッドロックが発生します。
これに対処するためには、ロックをかける時間を可能な限り短くする必要があります。
決してloopの中でロックし続けているなんて関数は書かないようにしてください。
ロックはライフタイムの終わりと同時に外れます。
そのため、可能な限りグローバル変数はブロックで囲って使いましょう。
{
let str_g = Str_g.write().unwrap();
*str_g = "piyo";
}