rust 閉包與同步
rust 閉包
rust閉包中主要包括兩個(gè)部分,閉包參數(shù)和閉包環(huán)境變量。
閉包函數(shù)和函數(shù)參數(shù)使用無太大區(qū)別。
閉包環(huán)境變量分為copy trait和非copy trait。
閉包分為move閉包和非move閉包。
copy trait變量,move閉包會(huì)將其單獨(dú)移植進(jìn)入閉包中,閉包內(nèi)可修改,外部原始變量不受影響。
copy trait變量,非move閉包會(huì)將其原始變量移植入閉包,閉包內(nèi)可修改,原始外部變量受影響。
非copy trait變量,move閉包會(huì)將其其單獨(dú)移植進(jìn)入閉包,閉包內(nèi)可修改,外部原始變量失效。
非copy trait變量,move閉包會(huì)將其移入閉包,閉包內(nèi)無法修改,外部原始變量不失效。
#[derive(Debug)]
pub struct Person {
pub name: String,
pub age: u32,
}
pub fn clone_struct_test_1() {
let person_a = Person {
name: String::from("wenbin"),
age: 12,
};
let closure_fn = || person_a;
let person_b = closure_fn();
println!("{:?}", person_b);
// println!("{:?}",person_a);
}
pub fn clone_struct_test_1_1() {
let mut person_a = Person {
name: String::from("wenbin"),
age: 12,
};
let closure_fn = || {
let mut person_c = Person {
name: person_a.name.clone(),
age: person_a.age + 5,
};
// this will report a error
// person_a.age = 17;
person_c
};
let person_b = closure_fn();
println!("{:?}", person_b);
println!("{:?}", person_a);
}
pub fn clone_struct_test_1_2() {
let mut person_a = Person {
name: String::from("wenbin"),
age: 12,
};
let closure_fn = move || {
let mut person_c = Person {
name: person_a.name.clone(),
age: person_a.age + 5,
};
person_a.age = person_a.age + 12;
(person_c, person_a)
};
let (person_b, person_a) = closure_fn();
println!("{:?}", person_b);
println!("{:?}", person_a);
}
pub fn clone_struct_test_2() {
let mut person_a = Person {
name: String::from("wenbin"),
age: 12,
};
let closure_fn = |person_a| person_a;
let mut person_b: &mut Person = closure_fn(&mut person_a);
person_b.age = 13;
println!("{:?}", person_b);
println!("{:?}", person_a);
}
pub fn clone_struct_test_2_1() {
let mut person_a = Person {
name: String::from("wenbin"),
age: 12,
};
let closure_fn = |person_a: &mut Person| {
let mut person_c = Person {
name: person_a.name.clone(),
age: person_a.age + 23,
};
person_c
};
let mut person_b = closure_fn(&mut person_a);
println!("{:?}", person_b);
person_b.age = 13;
println!("{:?}", person_b);
println!("{:?}", person_a);
}
rust 同步
rust共享變量同步有mutex,RWLock,atomic。
mutex通常與arc結(jié)合,一起在多線程中使用。在多線程中使用需要將arc指針進(jìn)行復(fù)制。
mutex的訪問主要通過lock方法,當(dāng)前線程阻塞時(shí),會(huì)自動(dòng)釋放鎖。
mutex自動(dòng)通知,在rust中提供了根據(jù)event來通知其他線程的機(jī)制condvar。
// 代碼中的Condvar就是條件變量,它提供了wait方法可以主動(dòng)讓當(dāng)前線程等待,
// 同時(shí)提供了notify_one方法,讓其他線程喚醒正在等待的線程。
// 這樣就能完美實(shí)現(xiàn)順序控制了。看起來好像條件變量把事都做完了,要Mutex干嘛呢?
// 為了防止多個(gè)線程同時(shí)執(zhí)行條件變量的wait操作,
// 因?yàn)闂l件變量本身也是需要被保護(hù)的,這就是鎖能做,而原子類型做不到的地方。
// 例子中可以看出,condvar和mutex想綁定,體現(xiàn)在wait方法:
// started = cvar.wait(started).unwrap();
pub fn sync_test_4(){
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();
// 創(chuàng)建一個(gè)新線程
thread::spawn(move|| {
let &(ref lock, ref cvar) = &*pair2;
println!("new thread start");
let mut started = lock.lock().unwrap();
*started = true;
thread::sleep_ms(10000);
cvar.notify_one();
println!("notify main thread");
});
// 等待新線程先運(yùn)行
let &(ref lock, ref cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
println!("before wait");
started = cvar.wait(started).unwrap();
println!("after wait");
}
}