这个问题源于@RalfJung发现了MutexGuard<Cell>并不是Sync的bug, 然后他提交的修复内容里面做了如下更改
unsafe impl<'a, T: ?Sized + Sync> Sync for MutexGuard<'a, T> { }
这里要求只有内部元素T满足Sync
的trait bound时, MutexGuard<T>
才是Sync
的, 因此!Sync
的Cell<T>
就无法跨线程共享了. 但是, 我对这个解决方案不能理解的地方在于, 为什么这个实现是一个unsafe
的实现? 请求前辈们解答!
1
共 6 条评论, 1 页
评论区
写评论因为它是对Mutex内部可变性API的状态封装
也就是说, 通常的使用场景是
#[derive(Send, Sync)]
(当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard
不能采用这种自动实现的方式?(啊, 这已经是第二个问题了...)也就是说, 通常的使用场景是
#[derive(Send, Sync)]
(当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard
不能采用这种自动实现的方式?(啊, 这已经是第二个问题了...)也就是说, 通常的使用场景是
#[derive(Send, Sync)]
(当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard
不能采用这种自动实现的方式?因为send,sync是unsafe trait,就是实现这个trait可能不安全。
Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)