Multithreading 等待并发线程的首选方法
我有一个在HTTP响应上循环的程序。这些不依赖于彼此,因此它们可以同时进行。我正在使用线程来执行此操作:Multithreading 等待并发线程的首选方法,multithreading,rust,Multithreading,Rust,我有一个在HTTP响应上循环的程序。这些不依赖于彼此,因此它们可以同时进行。我正在使用线程来执行此操作: extern crate hyper; use std::thread; use std::sync::Arc; use hyper::Client; fn main() { let client = Arc::new(Client::new()); for num in 0..10 { let client_helper = client.clone()
extern crate hyper;
use std::thread;
use std::sync::Arc;
use hyper::Client;
fn main() {
let client = Arc::new(Client::new());
for num in 0..10 {
let client_helper = client.clone();
thread::spawn(move || {
client_helper.get(&format!("http://example.com/{}", num))
.send().unwrap();
}).join().unwrap();
}
}
这是可行的,但我可以看到这样做的其他可能性,例如:
let mut threads = vec![];
threads.push(thread::spawn(move || {
/* snip */
for thread in threads {
let _ = thread.join();
}
对我来说,使用一个返回线程处理程序的函数也是有意义的,但我不知道怎么做。。。不确定返回类型必须是什么
等待Rust中并发线程的最佳/推荐方法是什么?您的第一个程序实际上没有任何并行性。每次启动工作线程时,您都会立即等待它完成,然后再启动下一个工作线程。当然,这比没用还糟糕
第二种方法是可行的,但是有些板条箱可以帮你做一些繁忙的工作。例如,和具有允许您编写以下内容的线程池(未测试,可能包含错误):
谢谢你的反馈。如果我在线程中做了大量工作,并且我想将其分离到一个函数中,那么我如何才能从该函数返回线程句柄并在以后加入线程?@ExplosionPills我建议将每个线程所做的工作提取到一个函数中,并将线程保留在它所在的位置。但是,如果您坚持认为,
std::thread::spawn
返回一个std::thread::JoinHandle
,其中T是闭包的返回类型(在您的例子中,()
)。作用域类型线程池的类似问题(我真的建议,它们不仅更简单,而且通常也稍微快一点)没有多大意义:您可以显式地加入线程,但它已经隐式地发生在作用域的末尾。这一切都是有意义的。我将研究使用作用域线程池。你能解释一下为什么线程上的.join()不是并发的,而是迭代器元素上的吗?你说的“在迭代器元素上”是指scope.spawn
?这是并发的,因为Scope::spawn
方法只存储连接句柄,而run_in_pool
在所有代码(整个| Scope |{…}
闭包)完成后,即在所有线程启动后,使用存储的句柄连接所有线程。.join()
等待线程完成。由于原始代码在继续循环生成下一个线程之前等待线程,因此它不是并发的。
let client = &Client::new();// No Arc needed
run_in_pool(|scope| {
for num in 0..10 {
scope.spawn(move || {
client.get(&format!("http://example.com/{}", num)).send().unwrap();
}
}
})