【发布时间】:2020-03-24 17:27:08
【问题描述】:
我有一个循环环形缓冲区(实现为向量),我希望一个线程定期写入环形缓冲区,另一个线程定期从环形缓冲区读取。只要访问向量的线程不在同一个索引处,是否可以创建一个可以同时读写的向量?
我希望达到的目标:
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
let vec = Arc::new(vec![Mutex::new(1), Mutex::new(2),Mutex::new(3)]);
{
let vec = vec.clone();
thread::spawn(move|| {
let mut s2 = *vec.get_mut(2).unwrap().lock().unwrap();
s2 = 7;
});
}
println!("{}", vec[2].lock().unwrap());
}
编译器输出为:
Compiling playground v0.0.1 (/playground)
warning: variable `s2` is assigned to, but never used
--> src/main.rs:12:21
|
12 | let mut s2 = *vec.get_mut(2).unwrap().lock().unwrap();
| ^^
|
= note: `#[warn(unused_variables)]` on by default
= note: consider using `_s2` instead
warning: value assigned to `s2` is never read
--> src/main.rs:13:13
|
13 | s2 = 7;
| ^^
|
= note: `#[warn(unused_assignments)]` on by default
= help: maybe it is overwritten before being read?
error[E0596]: cannot borrow data in an `Arc` as mutable
--> src/main.rs:12:27
|
12 | let mut s2 = *vec.get_mut(2).unwrap().lock().unwrap();
| ^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::sync::Arc<std::vec::Vec<std::sync::Mutex<i32>>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
被 rust 类型系统试图阻止竞争条件挫败 :(
我不想要的
- 一种涉及使锁定范围包括向量的实现。
- 不能选择对矢量进行原子读写,因为矢量将包含图像。
游乐场链接:
【问题讨论】:
-
您是否考虑过不自己实现,而是使用 docs.rs/crossbeam/0.3.2/crossbeam/sync/chase_lev/index.html 之类的东西?不确定这是否适用于您的情况,但从 API 角度来看,这听起来像是您想要的。
-
旁注:最好使用
Arc::clone()而不是arc.clone(),以免混淆您是克隆矢量还是弧。 -
关于您的错误,您根本不需要 get_mut 向量。锁定互斥体不需要 &mut。
-
关于您的问题:您的代码似乎与环形缓冲区没有任何相似之处。 “定期从环形缓冲区读取”是指它只是 读取,还是从环形缓冲区 poll(因此删除)某些内容?请澄清。
-
在
crossbeamcrate 的最新版本中,ArrayQueue提供了一个无锁环形缓冲区。
标签: multithreading rust thread-safety buffer