Multithreading 创建两个对Rust中的结构线程安全的可变引用
我试图在tokio中创建异步读写器,它们需要发送,并且必须是线程安全的。(似乎不是编写避免互斥的单线程tokio代码的方法) 读写器都需要交互,例如读取数据可能导致响应 我希望读写器都有一个线程安全的指向会话的指针,可以确保两者之间的通信Multithreading 创建两个对Rust中的结构线程安全的可变引用,multithreading,rust,mutex,reference-counting,Multithreading,Rust,Mutex,Reference Counting,我试图在tokio中创建异步读写器,它们需要发送,并且必须是线程安全的。(似乎不是编写避免互斥的单线程tokio代码的方法) 读写器都需要交互,例如读取数据可能导致响应 我希望读写器都有一个线程安全的指向会话的指针,可以确保两者之间的通信 /// function on the impl Session { pub fn split(&mut self, sock: TcpStream) -> (Reader, Writer) { let (read_half, wri
/// function on the
impl Session {
pub fn split(&mut self, sock: TcpStream) -> (Reader, Writer) {
let (read_half, write_half) = sock.split();
let session = Arc::new(RwLock::new(self)); // <- expected lifetime
( Reader::new(session, read_half), Writer::new(Arc::clone(session), write_half) )
}
...
}
pub struct Reader {
session: Arc<RwLock<&mut StompSession>>,
read_half: ReadHalf<TcpStream>,
...
pub struct Writer {
session: Arc<RwLock<&mut StompSession>>,
write_half: WriteHalf<TcpStream>,
....
上的函数
impl会话{
发布fn拆分(&mut self,sock:TcpStream)->(读写器){
让(读一半,写一半)=sock.split();
让session=Arc::new(RwLock::new(self));//让我们先清除一些内容: 似乎不是一种编写避免互斥的单线程tokio代码的方法
Mutex
要求与单线程无关,而是与可变借用有关。每当你产生一个未来,这个未来就是它自己的实体;它不是你的结构的神奇部分,而且最明显的是,它不知道如何保持&mut self
。这就是Mutex
的意义所在-它允许u动态获取对内部状态的可变引用,Arc
允许您在多个位置访问Mutex
本身
顺便说一句,它们的非同步等价物是Rc
和Cell
/RefCell
,它们的内容(无论是同步的还是非同步的)都应该是一个自有类型
Send
要求实际上是在tokio
之上使用futures
时出现的,因为它要求生成的futures必须是Send
(很明显,你可以使用spawn\u local
方法,但这会导致比它解决的问题更多的问题)
现在,回到你的问题。我将给你一个最短的路径来回答你的问题。然而,这并不是完全正确的方法;然而,由于我不知道你将在TcpStream
之上建立什么协议,或者你有什么样的需求,我无法为你指出正确的方向(然而)。评论就是出于这个原因出现的——给我更多的要求,我会很高兴地编辑这个
不管怎样。回到问题上来。既然互斥体
更好地用于自有类型,我们现在就要这样做,并“修复”您的读卡器
和写卡器
:
pub struct Reader {
session: Arc<RwLock<Session>>,
read_half: ReadHalf<TcpStream>,
}
pub struct Writer {
session: Arc<RwLock<StompSession>>,
write_half: WriteHalf<TcpStream>,
}
瞧,它编译了,每个编写器
/读卡器
对现在都有自己的可借用(可变和不可变)的会话引用
它突出显示了所做的更改。正如我所说,它现在起作用了,但当你试图做一些事情时,它会咬你的屁股,因为你需要在ReadHalf
和WriteHalf
上加上一些东西才能正确地使用它们。让我们先澄清一些事情:
似乎不是一种编写避免互斥的单线程tokio代码的方法
Mutex
要求与单线程无关,而是与可变借用有关。每当你产生一个未来,这个未来就是它自己的实体;它不是你的结构的神奇部分,而且最明显的是,它不知道如何保持&mut self
。这就是Mutex
的意义所在-它允许u动态获取对内部状态的可变引用,Arc
允许您在多个位置访问Mutex
本身
顺便说一句,它们的非同步等价物是Rc
和Cell
/RefCell
,它们的内容(无论是同步的还是非同步的)都应该是一个自有类型
Send
要求实际上是在tokio
之上使用futures
时出现的,因为它要求生成的futures必须是Send
(很明显,你可以使用spawn\u local
方法,但这会导致比它解决的问题更多的问题)
现在,回到你的问题。我将给你一个最短的路径来回答你的问题。然而,这并不是完全正确的方法;然而,由于我不知道你将在TcpStream
之上建立什么协议,或者你有什么样的需求,我无法为你指出正确的方向(然而)。评论就是出于这个原因出现的——给我更多的要求,我会很高兴地编辑这个
不管怎样。回到问题上来。既然互斥体
更好地用于自有类型,我们现在就要这样做,并“修复”您的读卡器
和写卡器
:
pub struct Reader {
session: Arc<RwLock<Session>>,
read_half: ReadHalf<TcpStream>,
}
pub struct Writer {
session: Arc<RwLock<StompSession>>,
write_half: WriteHalf<TcpStream>,
}
瞧,它编译了,每个编写器
/读卡器
对现在都有自己的可借用(可变和不可变)的会话引用
这突出显示了所做的更改。正如我所说,它现在可以工作了,但当你试图做某事时,它会咬你的屁股,因为你需要在ReadHalf
和WriteHalf
上加些东西才能正确使用它们。你知道(或板条箱)?你知道(或板条箱)吗?好的,这很有意义,我已经做到了,在WriteHalf上有一个类似的Arc>锁,read-half可能需要同样的锁来强制关闭它。我希望所有这些锁都很快:)不会梦想在Java中编写同步代码或在C中编写Mutex。顺便说一句,协议是STOMP()@teknopaul如果由于某种原因您的锁定操作最终被阻塞,futures\u locks
板条箱包含未来优化的锁定原语。还有其他(非锁定)选项提供了同样的东西;归根结底,这是关于你有什么约束。@teknopaul实际上。我突然想到一件事——你为什么认为这与java不同?Mutex
本质上是同步的,因为底层行为是