advance-practice1/multi-threads #1157
Replies: 15 comments 19 replies
-
前面学的好好的,学到这里看不懂了~~~~~~~呜呜 |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
thread '' panicked at 'called |
Beta Was this translation helpful? Give feedback.
-
各位大哥,小白有个地方不懂,还望大哥解答一下: impl Worker {
//Arc 允许多个 Worker 同时持有 receiver,而 Mutex 可以确保一次只有一个 Worker 能从 receiver 接收消息。
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(
move || {
loop {
//receiver一直持有锁,直到recv到消息,并且执行完job,那么其他的worker是不是就无法给receiver上锁了?
let job = receiver.lock().unwrap().recv().unwrap();
println!("Worker {id} got a job; executing.");
job();
}
}
);
// 每个 `Worker` 都拥有自己的唯一 id
Worker { id, thread }
}
} let job = receiver.lock().unwrap().recv().unwrap(); |
Beta Was this translation helpful? Give feedback.
-
这个报错怎么解决呀 |
Beta Was this translation helpful? Give feedback.
-
type Job = Box<dyn FnOnce() + Send + 'static>; 请问这里dyn分发的是 |
Beta Was this translation helpful? Give feedback.
-
有一个问题呀,这看起来worker是多线程的,但是发送者其实还是只有一个线程,那是不是说明如果发送者被阻塞了,其实整体还是都会被阻塞住?也就是我在pool.execute被比如某段垃圾代码阻塞了,那后续进来的请求就都没法执行响应了? |
Beta Was this translation helpful? Give feedback.
-
打螺丝会了 该造飞机了 |
Beta Was this translation helpful? Give feedback.
-
整体逻辑大概应该是看懂了-好像很简单我还看了好几遍才梳理通:( :ThreadPoll 在new的时候通过worker创建4个线程,和一个channel,让worker一直准备接受数据。当web界面接受点击时,用execute函数通过channel进行传输。例子中还有很多用法需要再好好研究。 |
Beta Was this translation helpful? Give feedback.
-
写出来了,但是我理解的线程池,不就是0线程阻塞,就到1线程上运行吗,我线程池开为2两个,然后阻塞10s,然后用两个页面访问/sleep,再用一个访问原始路径,这个原始路径竟然没阻塞 |
Beta Was this translation helpful? Give feedback.
-
rust有什么推荐的线程池库吗,找了一下没找到 |
Beta Was this translation helpful? Give feedback.
-
hi,我有一个疑问,我测试的时候是按照(慢请求,快请求,慢请求)的顺序进行测试的。第一个慢请求按照预期再5秒后返回,第二个快请求也是按照预期瞬间返回,但是最后的这个慢请求却是要等到第一个慢请求完成后再等待5秒才会进行返回。大佬能否解释一下最后一个请求的行为,谢谢 |
Beta Was this translation helpful? Give feedback.
-
为什么请求一次会有三个线程进行接受任务但是只有一个成功其余两个失败?看博主的仿佛不是这样,是因为调用出的代码是async的吗? use std::{
sync::{mpsc, Arc, Mutex},
thread,
};
pub struct ThreadPool {
workers: Vec<Worker>,
sender: mpsc::Sender<Job>,
}
type Job = Box<dyn FnOnce() + Send + 'static >;
impl ThreadPool {
pub fn new(size: usize) -> ThreadPool {
assert!(size > 0);
let (sender, receiver) = mpsc::channel();
let receiver = Arc::new(Mutex::new(receiver));
let mut workers = Vec::with_capacity(size);
for id in 0..size {
workers.push(Worker::new(id, Arc::clone(&receiver)));
}
ThreadPool {workers, sender}
}
/// Create a new ThreadPool
/// The size is the number of threads in the pool.
///
/// # Panics
///
/// The `new` function will panic if the size is zero.
pub fn execute<F>(&self,f: F)
where
F: FnOnce() +Send + 'static,
{
let job = Box::new(f);
self.sender.send(job).unwrap();
}
}
struct Worker {
id: usize,
thread: thread::JoinHandle<()>,
}
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker {
let thread = thread::spawn(move || loop {
let job = match receiver.lock().unwrap().recv() {
Ok(x) => x,
Err(e) => {
panic!("Worker {id} got a error: {:?}", e);
},
};
println!("Worker {id} got a job; executing.");
job();
});
Worker {id, thread}
}
} 输出如下:
|
Beta Was this translation helpful? Give feedback.
-
啥时候该用 async/await,啥时候该用线程池呀。真的头大,不知道怎么抉择。感觉 async/await 多是用于已经比较明确异步函数代码该写在什么地方的场景,而线程池是不太清楚任务会在哪块代码和什么时候提交任务的场景。 |
Beta Was this translation helpful? Give feedback.
-
advance-practice1/multi-threads
https://course.rs/advance-practice1/multi-threads.html
Beta Was this translation helpful? Give feedback.
All reactions