我需要不安全地定義一個可以在 2 個執行緒之間共享的 Rust 結構,并從兩個執行緒中改變結構的內容。
我不想使用Mutex,也RwLock不想自己實作執行緒安全。出于性能方面的考慮,我不想在我想訪問內容時檢查互斥鎖,并且我知道它不在關鍵部分。
如果我只用于Arc在執行緒之間共享結構,我會得到cannot borrow data in an Arc as mutableand help: trait DerefMut is required to modify through a dereference, but it is not implemented for std::sync::Arc<Foo>。
執行此操作的安全方法:
struct Foo {
bar: usize,
}
impl Foo {
pub fn set_bar(&mut self, a: usize) {
self.bar = a;
}
}
fn main() {
let mut foo = Foo { bar: 32 };
foo.bar = 33;
let foo_arc = std::sync::Arc::new(std::sync::Mutex::new(foo));
let foo_arc_2 = std::sync::Arc::clone(&foo_arc);
let handle = std::thread::spawn(move || {
foo_arc_2.lock().unwrap().set_bar(32);
});
foo_arc.lock().unwrap().set_bar(31);
handle.join().unwrap();
}
我不安全地想要實作的目標:
struct Foo {
bar: usize,
// My own lock
// lock: std::sync::Mutex<usize>,
}
unsafe impl Sync for Foo {}
impl Foo {
pub fn set_bar(&mut self, a: usize) {
self.bar = a;
}
}
fn main() {
let mut foo = Foo { bar: 32 };
foo.bar = 33;
let foo_arc = std::sync::Arc::new(foo);
let foo_arc_2 = std::sync::Arc::clone(&foo_arc);
let handle = std::thread::spawn(move || {
foo_arc_2.set_bar(32);
});
foo_arc.set_bar(31);
handle.join().unwrap();
}
我可能不必使用Arc和使用目前我不知道的更低級別的東西。
uj5u.com熱心網友回復:
如果您想這樣做以便以后在生產中使用它,請不要這樣做!許多比你我更聰明的人已經正確地做到了這一點。改用他們寫的。如果您想將此作為練習或學習目的,請繼續進行。
如果要提供具有內部可變性的型別,則必須使用UnsafeCell. 這種型別是 rust 中每個內部可變性的核心,使用它是獲取&mut Tfrom&T的唯一方法。您應該仔細閱讀它的檔案、cell模塊的檔案和 The Nomicon(最好是全部,但至少是并發章節)。
如果你喜歡看 視頻,Jon Gjengset 有很多關于細胞型別的精彩視頻。還有這個關于原子記憶體和實作(壞)互斥鎖的視頻。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/517029.html
標籤:多线程锈不安全
