文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
11.3 同步
通道是单所有权,一旦值被发送,将无法再次使用。某些时候,内存共享有实际需求。标准库提供 互斥 用于资源和逻辑保护。但面对多线程共享时,需额外的 原子引用计数 来启用多所有权。
Arc
: 共享所有权,并发安全的原子引用计数。Mutex
: 互斥锁,安全可变性(&mut T
),非递归锁。RwLock
: 读写锁(&T
,&mut T
)。Atomic
: 原子操作(内部可变性)。
Barrier
: 设置屏障,让所有参与线程同时开始。Condvar
: 阻塞等待,直到条件变量发出通知。Once
: 单次执行。
将所有权交给 Mutex
,随后通过它的访问被互斥。没有解锁方法,临界区大小可通过作用域或调用 drop
调节。
如果没有要保护的数据,可使用
Mutex<()>
,像其他语言那样使用。
use std::thread; use std::sync::{Mutex, Arc}; fn main() { let v = vec![1, 2, 3]; let d = Mutex::new(v); // move! { let mut p = d.lock().unwrap(); p.push(4); } // unlock! { let mut p = d.lock().unwrap(); // lock or block! p.push(5); } // unlock! println!("{:?}", d); } // Mutex { data: [1, 2, 3, 4, 5], poisoned: false, .. }
fn main() { let v = vec![1, 2, 3]; let d = Mutex::new(v); // move! let mut p = d.lock().unwrap(); p.push(4); drop(p); let mut p = d.lock().unwrap(); p.push(5); drop(p); println!("{:?}", d); } // Mutex { data: [1, 2, 3, 4, 5], poisoned: false, .. }
在智能指针一节中,我们用 Rc<RefCell>
来实现可变所有权共享,但那不是并发安全的。
可以说,
Arc<Mutex>
是RefCell
并发版本,而Atomic
是Cell
并发版本。
use std::thread::scope; use std::sync::{Mutex, Arc}; fn main() { let data = Arc::new(Mutex::new(vec![])); scope(|s| { for _ in 1..3 { s.spawn({ // 表达式块,返回闭包! let d = data.clone(); move || { let mut v = d.lock().unwrap(); for i in 1..=10 { v.push(i); } } }); } }); println!("{:?}", data.lock().unwrap()); }
// mod util; // use util::*; use std::thread::{ scope, park }; use std::sync::{ RwLock, Arc }; fn main() { let data = Arc::new(RwLock::new(vec![])); scope(|s| { // reader let t = s.spawn({ let d = data.clone(); move || { park(); // sleep ! let v = d.read().unwrap(); println!("{:?}", v); } }); // writer s.spawn({ let d = data.clone(); move || { let mut v = d.write().unwrap(); for i in 1..=10 { v.push(i); } t.thread().unpark(); // weakup! } }); }); }
标记
两个相关特征,标记(marker)类型是否线程安全(thread safely)。
Send
:跨线程传递(move)安全。Sync
:多线程共享(&T)安全。
impl<T> Send for Arc<T> impl<T> Sync for Arc<T>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论