use std::collections::HashMap;
pub fn frequency(input: &[&str], worker_count: usize) -> HashMap<char, usize> {
let (tx, rx) = std::sync::mpsc::channel();
let mut hndls = Vec::new();
{
// вычисляем количество потоков и размер порции
let mut portion = 10; //минимальная порция
let len = input.len();
let mut cnt = (len as f64 / portion as f64 + 0.5) as usize;
cnt = if cnt > worker_count {cnt} else {worker_count};
portion = (len as f64 / cnt as f64 + 0.5) as usize;
for (i, chank) in input.chunks(portion).enumerate() {
let tx_local = tx.clone();
let chank_local = chank.clone();
let handl = std::thread::spawn(move || {
let mut mp_local = HashMap::new();
//mp_local.insert('a', 1);
for s in chank_local {
for ch in s.to_lowercase().chars() {
if let Some(val) = mp_local.get_mut(&ch) {
*val += 1;
} else {
mp_local.insert(ch, 1);
}
}
}
if let Err(e) = tx_local.send(mp_local) {
eprintln!("Ошибка записи в канал потоком {i}: {e}");
}
});
hndls.push(handl);
}
}
drop(tx);
let mut mp = HashMap::new();
for mp_local in rx {
for (k,v) in mp_local {
if let Some(val) = mp.get_mut(&k) {
*val += v;
} else {
mp.insert(k, v);
}
}
}
for handl in hndls {
handl.join().unwrap();
}
mp
}
错误:
error[E0521]: borrowed data escapes outside of function
--> src/lib.rs:19:25
|
3 | pub fn frequency(input: &[&str], worker_count: usize) -> HashMap<char, usize> {
| ----- - let's call the lifetime of this reference `'1`
| |
| `input` is a reference that is only valid in the function body
...
19 | let handl = std::thread::spawn(move || {
| _________________________^
20 | | let mut mp_local = HashMap::new();
21 | |
22 | | //mp_local.insert('a', 1);
... |
35 | | }
36 | | });
| | ^
| | |
| |______________`input` escapes the function body here
| argument requires that `'1` must outlive `'static`
error[E0521]: borrowed data escapes outside of function
--> src/lib.rs:19:25
|
3 | pub fn frequency(input: &[&str], worker_count: usize) -> HashMap<char, usize> {
| ----- - let's call the lifetime of this reference `'2`
| |
| `input` is a reference that is only valid in the function body
...
19 | let handl = std::thread::spawn(move || {
| _________________________^
20 | | let mut mp_local = HashMap::new();
21 | |
22 | | //mp_local.insert('a', 1);
... |
35 | | }
36 | | });
| | ^
| | |
| |______________`input` escapes the function body here
| argument requires that `'2` must outlive `'static`
For more information about this error, try `rustc --explain E0521`.
error: could not compile `parallel-letter-frequency` (lib test) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `parallel-letter-frequency` (lib) due to 2 previous errors
我没有运行它,但纯粹是出于一般原因:
chank.clone
它不会克隆它所包含的对象。因此,链接的生命周期chank_local
等于参数 中的链接的生命周期input
。关键字move
无法移位,chank_local
因为该值包含生命周期与其自身不同且不同于 的引用'static
。未经测试!
您不需要克隆该块,而是复制该块中的所有值:
该指令
move
会将生成的行传递给作为参数的闭包spawn
,并且当闭包完成时,内存将被释放。或者像这样: