遅いリクエストを実装
use std::thread; use std::time::Duration; // let get = b"GET / HTTP/1.1\r\n"; let sleep = b"GET /sleep HTTP/1.1\r\n"; let(status_line, filename) = if buffer.starts_with(get) { ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") } else if buffer.starts_with(sleep){ thread::sleep(Duration::from_secs(5)); ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") } else { ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") };
### スレッドプール
タスクを処理する準備のできた一塊の大量に生成されたスレッド
ただし、固定された数のスレッドにすることで、無制限に大量生産してDos攻撃の被害に遭うことを抑える。
fn main() { let listner = TcpListener::bind("127.0.0.1:7878").unwrap(); for stream in listner.incoming() { let stream = stream.unwrap(); thread::spawn(||{ handle_connection(stream); }); } }
スレッド数を限定する
use std::thread; pub struct ThreadPool { workers: Vec<Worker>, } impl ThreadPool { pub fn new(size: usize) -> ThreadPool { assert!(size > 0); let mut threads = Vec::with_capacity(size); for _ in 0..size { workers.push(Worker::new(id)); } ThreadPool { workers } } pub fn execute<F>(&self, f: F) where F: FnOnce() + Send + 'static { } } struct Worker { id: usize, thread: thread::JoinHandle<()>, } impl Worker { fn new(id: usize) -> Worker { let thread = thread::spawn(||{}); Worker { id, thread, } } }
use std::thread; use std::sync::mpsc; use std::sync::Arc; use std::sync::Mutex; pub struct ThreadPool { workers: Vec<Worker>, sender: mpsc::Sender<Job>, } trait FnBox { fn call_box(self: Box<Self>); } impl<F: FnOnce()> FnBox for F { fn call_box(self: Box<F>){ (*self)() } } type Job = Box<dyn FnBox + 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, } } 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 = receiver.lock().unwrap().recv().unwrap(); println!("Worker {} got a job; executing.", id); job.call_box(); } }); Worker { id, thread, } } }
Worker 0 got a job; executing.
Worker 1 got a job; executing.
Worker 2 got a job; executing.
Worker 3 got a job; executing.
Worker 0 got a job; executing.