【发布时间】:2021-11-29 11:59:08
【问题描述】:
我正在尝试使用Arc<Mutex<T>> 模式给HashMap 写信,作为受the Rust cookbook 启发的网站抓取练习的一部分。
第一部分使用tokio 运行时。我无法完成正在完成的任务并返回 HashMap,因为它只是挂起。
type Db = Arc<Mutex<HashMap<String, bool>>>;
pub async fn handle_async_tasks(db: Db) -> BoxResult<HashMap<String, bool>> {
let links = NodeUrl::new("https://www.inverness-courier.co.uk/")
.await
.unwrap();
let arc = db.clone();
let mut handles = Vec::new();
for link in links.links_with_paths {
let x = arc.clone();
handles.push(tokio::spawn(async move {
process(x, link).await;
}));
}
// for handle in handles {
// handle.await.expect("Task panicked!");
// } < I tried this as well>
futures::future::join_all(handles).await;
let readables = arc.lock().await;
for (key, value) in readables.clone().into_iter() {
println!("Checking db: k, v ==>{} / {}", key, value);
}
let clone_db = readables.clone();
return Ok(clone_db);
}
async fn process(db: Db, url: Url) {
let mut db = db.lock().await;
println!("checking {}", url);
if check_link(&url).await.is_ok() {
db.insert(url.to_string(), true);
} else {
db.insert(url.to_string(), false);
}
}
async fn check_link(url: &Url) -> BoxResult<bool> {
let res = reqwest::get(url.as_ref()).await?;
Ok(res.status() != StatusCode::NOT_FOUND)
}
pub struct NodeUrl {
domain: String,
pub links_with_paths: Vec<Url>,
}
#[tokio::main]
async fn main() {
let db: Db = Arc::new(Mutex::new(HashMap::new()));
let db = futures::executor::block_on(task::handle_async_tasks(db));
}
我想将HashMap 返回到主线程被阻塞的main()。如何等待所有异步线程进程完成并返回HashMap?
【问题讨论】:
-
你能提供你的
main()函数吗?否则没有人能告诉你如何使用那里的HashMap -
除了我的回答之外,我建议在没有任何 Rust 经验的情况下不要直接跳入
async的东西。 -
@orlp 我用我正在使用的实际 url 和
main()函数更新了我的问题。 @sebpuetz -
@godhar
NodeUrl是什么? -
@orlp 它返回一个带有相对路径的 URL 的 Vec。它工作正常。
标签: multithreading rust tokio