Hi,
I am trying to write a program which calculates number of directories under specific path while at the same time displaying number of found directories. Could you please help me fix it ?
Thank you
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use walkdir::WalkDir;
fn main() {
let total_dirs = Arc::new(Mutex::new(0));
let total_dirs_clone = Arc::clone(&total_dirs);
thread::spawn(move || {
let mut num_dirs = total_dirs_clone.lock().unwrap();
for entry in WalkDir::new("/").into_iter().filter_map(Result::ok) {
if entry.file_type().is_dir() {
*num_dirs += 1;
}
thread::sleep(Duration::from_millis(1));
}
});
loop {
let total_dirs_clone = Arc::clone(&total_dirs);
let num_dirs = total_dirs_clone.lock().unwrap();
println!("Total directories found {}", num_dirs);
thread::sleep(Duration::from_millis(200));
}
}
You're not releasing the locks when they aren't used, so the first thread to get hold on the lock holds it until the end of work (for walker thread) or until the end of current iteration (for printing thread). Lock the mutex right before using the value and drop the lock immediately afterwards, and all should work.
Thank you @Cerber-Ursi, your comment was really helpful.
Code runs now, but I don't understand why it's so slow.
This runs almost instantly:
use std::thread;
use std::time::{Duration};
use walkdir::WalkDir;
fn main() {
thread::spawn(move || {
let mut found_dirs = 0;
for entry in WalkDir::new("/Users/User/")
.into_iter()
.filter_map(Result::ok)
{
if entry.file_type().is_dir() {
found_dirs += 1;
println!("{}", found_dirs);
}
}
});
loop {
println!("Sleeping for 1 sec");
thread::sleep(Duration::from_millis(1000));
}
}
While code using mutexes is 100s times slower:
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use walkdir::WalkDir;
fn main() {
let total_dirs = Arc::new(Mutex::new(0));
let total_dirs_clone = Arc::clone(&total_dirs);
thread::spawn(move || {
for entry in WalkDir::new("/Users/User/")
.into_iter()
.filter_map(Result::ok)
{
if entry.file_type().is_dir() {
let mut num_dirs = total_dirs_clone.lock().unwrap();
*num_dirs += 1;
}
}
});
loop {
let total_dirs_clone = Arc::clone(&total_dirs);
let num_dirs = total_dirs_clone.lock().unwrap();
println!("Total directories found {}", num_dirs);
thread::sleep(Duration::from_millis(1000));
}
}
Could you please point me to where the problem could be ?