< 返回我的博客

Junjie Huang 发表于 2018-01-28 23:48

Tags:bug解决方案讨论

这个问题源于@RalfJung发现了MutexGuard<Cell>并不是Sync的bug, 然后他提交的修复内容里面做了如下更改

unsafe impl<'a, T: ?Sized + Sync> Sync for MutexGuard<'a, T> { }

这里要求只有内部元素T满足Sync的trait bound时, MutexGuard<T>才是Sync的, 因此!SyncCell<T>就无法跨线程共享了. 但是, 我对这个解决方案不能理解的地方在于, 为什么这个实现是一个unsafe的实现? 请求前辈们解答!

评论区

写评论
CrLF0710 2018-01-29 02:07

因为它是对Mutex内部可变性API的状态封装

@Junjie Huang 也就是说, 通常的使用场景是#[derive(Send, Sync)](当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard不能采用这种自动实现的方式?(啊, 这已经是第二个问题了...)

@CrLF0710 Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)

作者 Junjie Huang 2018-01-28 23:59

也就是说, 通常的使用场景是#[derive(Send, Sync)](当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard不能采用这种自动实现的方式?(啊, 这已经是第二个问题了...)

@CrLF0710 Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)

作者 Junjie Huang 2018-01-28 23:59

也就是说, 通常的使用场景是#[derive(Send, Sync)](当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard不能采用这种自动实现的方式?(啊, 这已经是第二个问题了...)

@Junjie Huang 也就是说, 通常的使用场景是#[derive(Send, Sync)](当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard不能采用这种自动实现的方式?

@CrLF0710 Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)

作者 Junjie Huang 2018-01-28 23:58

也就是说, 通常的使用场景是#[derive(Send, Sync)](当且仅当被实现的enum/struct是Send, Sync), 而手动实现则是要责任自负0. 0 那为什么MutexGuard不能采用这种自动实现的方式?

@CrLF0710 Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)

wspsxing 2018-01-28 23:51

因为send,sync是unsafe trait,就是实现这个trait可能不安全。

CrLF0710 2018-01-28 23:51

Send 和 Sync 是auto trait。当需要自己代码里手工指定 Send 或者 !Send 的时候(从而替代自动推导出的结果),总是需要加unsafe关键字(表示责任自负)

1 共 6 条评论, 1 页