multithreading - 如何使用 self 中的方法使用函数?
问题描述
在尝试编写一些并行代码时,我不断遇到如下错误。我找到了一些解决方案,但它们都涉及我不想做的锁定。有什么办法可以解决这个问题吗?
pub trait PermBrute {
fn quadgram( &self, max_len: usize, ciphertext: &String ) -> Vec<usize> {
let mut vec : Vec<(f64, Vec<usize>)> = Vec::new();
let results = Arc::new(Mutex::new(vec));
let mut threads = vec![];
for i in 0..*CPUS {
threads.push( thread::spawn({
let clone = Arc::clone(&results);
let text = ciphertext.clone();
move || {
// some code here
let hold = self.decrypt( )
// some more code here
let mut v = clone.lock().unwrap();
v.push(best_key);
}
}));
}
for t in threads {
t.join().unwrap();
}
let lock = Arc::try_unwrap(results).expect("Lock still has multiple owners");
let mut hold = lock.into_inner().expect("Mutex cannot be locked");
// do some stuff with hold and return out
return out;
}
fn decrypt( &self, ciphertext : &String, key : &Vec<usize>) -> String;
}
error[E0277]: `Self` cannot be shared between threads safely
--> src/ciphers/cipher.rs:131:27
|
108 | fn quadgram( &self, max_len: usize, ciphertext: &String ) -> Vec<usize> {
| - help: consider further restricting `Self`: `where Self: std::marker::Sync`
...
131 | threads.push( thread::spawn({
| ^^^^^^^^^^^^^ `Self` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `Self`
= note: required because of the requirements on the impl of `std::marker::Send` for `&Self`
= note: required because it appears within the type `[closure@src/ciphers/cipher.rs:140:17: 164:18 text:std::string::String, start_len:usize, end_len:usize, count:usize, start_points_clone:std::vec::Vec<usize>, local_self:&Self, end:usize, clone:std::sync::Arc<std::sync::Mutex<std::vec::Vec<(f64, std::vec::Vec<usize>)>>>]`
解决方案
使用rayon crate,这可以使用并行迭代器技术来完成。
pub trait PermBrute {
fn quadgram(&self, max_len: usize, ciphertext: &String) -> Vec<usize> {
let mut vec: Vec<(f64, Vec<usize>)> = Vec::new();
let mut threads = vec![];
let best_keys: Vec<_> = (0..*CPUS)
.into_par_iter()
.map(|i| {
// some code here
// you can access `ciphertext` here directly without copying
todo!();
// some more code here
best_key
})
.collect();
// do some stuff with best_keys and return out
return out;
}
fn decrypt(&self, ciphertext: &String, key: &Vec<usize>) -> String;
}
推荐阅读
- azure - Docker:“在 Azure 上部署 Docker 容器”说明
- pine-script - Pinescript 条件线绘图
- pandas - 如何更改 cartopy 地图中颜色条的类型?
- python - 如何通过使用 Python 对特定列进行分组来求和?
- c# - 如何在新的 MSTests 中运行测试序列?
- python - 为什么使用后向差分编码时会丢失列?
- python - 从 For 循环创建 Numpy 数组时出现索引错误
- amazon-web-services - 在 CDK 中编辑 API 文档
- javascript - 当 localStorage 中为 false 时,复选框状态总是变为 true
- macos - rsync 2.6.9 风格的日志记录与 rsync 3.x