memory-management - 用Rust中的人造丝和Indicatif进行内存泄漏

标签 memory-management rust rayon

因此,我正在尝试对哈希进行详尽的搜索。哈希本身在这里并不重要。因为我想使用CPU的所有处理能力,所以我在使用Rayon来获取线程池和许多任务。搜索算法如下:

let (tx, rx) = mpsc::channel();

let original_hash = String::from(original_hash);

rayon::spawn(move || {
    let mut i = 0;
    let mut iter = SenhaIterator::from(initial_pwd);
    while i < max_iteracoes {
        let pwd = iter.next().unwrap();

        let clone_tx = tx.clone();
        rayon::spawn(move || {
            let hash = calcula_hash(&pwd);
            clone_tx.send((pwd, hash)).unwrap();
        });

        i += 1;
    }
});

let mut last_pwd = None;
let bar = ProgressBar::new(max_iteracoes as u64);

while let Ok((pwd, hash)) = rx.recv() {
    last_pwd = Some(pwd);
    if hash == original_hash {
        bar.finish();
        return last_pwd.map_or(ResultadoSenha::SenhaNaoEncontrada(None), |s| {
            ResultadoSenha::SenhaEncontrada(s)
        });
    }
    bar.inc(1);
}
bar.finish();
ResultadoSenha::SenhaNaoEncontrada(last_pwd)
只是一个高层次的解释:随着任务完成工作,它们会向主线程发送一对(密码,哈希),该哈希将哈希与原始哈希(我正在尝试为之寻找密码的哈希)进行比较。 )。如果它们匹配,那就太好了,我将使用表示成功的枚举值和产生原始哈希值的密码返回main。在所有迭代结束之后,我将使用一个enum值返回main,该值指示未找到哈希,但是使用最后一个密码,因此我可以在以后的运行中从这一点重试。
我正在尝试使用Indicatif来显示进度栏,因此我可以一窥进度。
但是我的问题是该程序正在增加其内存使用量,而没有明确的原因。如果我让它运行10亿次迭代,它会慢慢增加内存,直到填满所有可用的系统内存。
但是,当我注释bar.inc(1);行时,程序的行为与预期的一样,并且具有正常的内存使用率。
我已经创建了带有Rayon和Indicatif的测试程序,但是没有哈希计算并且可以正常工作,没有内存异常。
这使我认为我的代码中的内存管理有问题,但是看不到任何明显的东西。

最佳答案

我找到了解决方案,但是我仍然不确定为什么它可以解决原始问题。
我要做的是将进度代码传输到第一个生成的闭包中。请看下面的第6和19行:

let (tx, rx) = mpsc::channel();

let original_hash = String::from(original_hash);

rayon::spawn(move || {
    let mut bar = ProgressBar::new(max_iteracoes as u64);
    let mut i = 0;
    let mut iter = SenhaIterator::from(initial_pwd);
    while i < max_iteracoes {
        let pwd = iter.next().unwrap();

        let clone_tx = tx.clone();
        rayon::spawn(move || {
            let hash = calcula_hash(&pwd);
            clone_tx.send((pwd, hash)).unwrap();
        });

        i += 1;
        bar.inc();
    }
    bar.finish();
});

let mut latest_pwd = None;

while let Ok((pwd, hash)) = rx.recv() {
    latest_pwd = Some(pwd);
    if hash == original_hash {
        return latest_pwd.map_or(PasswordOutcome::PasswordNotFound(None), |s| {
            PasswordOutcome::PasswordFound(s)
        })
    }
}
PasswordOutcome::PasswordNotFound(latest_pwd)
第一个生成关闭的角色是获取下一个密码,以尝试将其传递给工作程序任务,该工作程序计算相应的哈希并将该对(密码,哈希)发送到主线程。主线程将等待来自rx channel 的对,并与预期的哈希值进行比较。
我仍然缺少的是为什么跟踪外线程的进度会泄漏内存。我无法确定真正泄漏的是什么。但是它现在正在工作,我对结果感到满意。

关于memory-management - 用Rust中的人造丝和Indicatif进行内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64729949/

相关文章:

java - 垃圾收集器与池

c++ - 为什么我们不能删除一个初始化的指针?

python - 用python衡量内存的使用情况

C++ 删除指针(释放内存)

rust - 如何从Rayon的 `par_iter()`引起 panic ?

reference - 有什么方法可以返回对在函数中创建的变量的引用?

rust - 对于返回 &str 或具有父级生命周期的新字符串的方法,返回类型应该是什么?

rust - 如何查看添加了头部和尾部的切片?

rust - Rayon 如何防止在线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?

multithreading - 使用rusoto使用rust AWS分段上传,对 'there is no reactor running …`感到 panic 的多线程(人造丝)