Rust线程池

Rust 实现线程池服务器 初级版

use std::net::TcpListener;
use std::net::TcpStream;
use std::io::Read;
use std::io::Write;
use std::fs;
use std::time::Duration;
use std::thread;
use std::sync::mpsc;
use std::sync::Arc;
use std::sync::Mutex;

pub struct ThreadPool{
    workers:Vec<Worker>,
    sender:mpsc::Sender<Message>,
}
type Job =Box<dyn FnOnce() +Send +'static>; //Box 存储的是闭包

//为了程序退出,必须通过闭包的形式通知
enum Message{
    NewJob(Job),//执行仍无,闭包
    Terminate,//退出消息
}

impl ThreadPool{
    pub fn new(size:usize)->ThreadPool{
        assert!(size>0);
        //创建通道(队列)
        let (sender,receiver) = mpsc::channel();
        let receiver = Arc::new(Mutex::new(receiver));
        //创建work,然后保存到workers
        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(Message::NewJob(job)).unwrap();
    }
}
impl Drop for ThreadPool{
    fn drop(&mut self){
        println!("drop ThreadPool");
        //1怎么通知线程退出,之前c把某个线程置位
        //发送一个退出的消息
        for _ in & self.workers{
            self.sender.send(Message::Terminate).unwrap();
        }

        //2 等待所有线程退出
        println!("wait work terminate...");
        // for worker in &mut self.workers{
        //     println!("work {} shutdown...",worker.id);
        //     worker.thread.join().unwrap();
        // }
        for worker in &mut self.workers{
            println!("work {} shutdown...",worker.id);
            if let Some(thread) = worker.thread.take(){//take取出所有权
                thread.join().unwrap();
            }
        }
    }
}
//封装线程
struct Worker{
    id:usize,
    // thread:thread::JoinHandle<()>,
    thread:Option<thread::JoinHandle<()>>,
}
impl Worker{
    pub fn new(id:usize,receiver:Arc<Mutex<mpsc::Receiver<Message>>>)->Worker{
        let thread1 = thread::spawn(move ||loop{
            let message = receiver.lock().unwrap().recv().unwrap();
            match message{
                Message::NewJob(job)=>{
                    println!("work:{},get a job",id);
                    job();
                },
                Message::Terminate =>{
                    println!("work:{}was told to terminate",id);
                    break;
                }
            }
            
        });
        Worker{id,thread:Some(thread1)}//此处名字与Worker里要一致
    }
}
fn main(){
    let listener = TcpListener::bind("0.0.0.0:3333").unwrap();
    println!("bind ok and listen port 3333");

    let pool = ThreadPool::new(4);//线程池
    for stream in listener.incoming().take(2){//take(2)运行两次退出可以去掉
        match stream{
            Ok(stream)=>{
                println!("new connect");
                pool.execute(||{//传闭包
                     handle_connectuin(stream);
                });
            },
            Err(e)=>{
                println!("Error:{:?}",e);
            }
        }
    }
    drop(pool);
}
//读取消息
fn handle_connectuin(mut stream:TcpStream){
    let mut buffer = [0 as u8;1024];
    stream.read(&mut buffer).unwrap();
    // println!("req:{}",String::from_utf8_lossy(&buffer[..]));

    //匹配get   /
    //匹配get   /hello
    let get = b"GET / HTTP/1.1\r\n";
    let get_sleep = b"GET /sleep HTTP/1.1\r\n";
    if buffer.starts_with(get){
        //读取文件
        let contents = fs::read_to_string("hello.txt").unwrap();

        //回复客户端
        let responese = format!(
            "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
            contents.len(),
            contents
        );
        // let responese ="HTTP/1.1 200 OK\r\n\r\nwanying";
        stream.write(responese.as_bytes()).unwrap();
        stream.flush().unwrap();
    }else if buffer.starts_with(get_sleep){

        thread::sleep(Duration::from_secs(20));
        //读取文件
        let contents = fs::read_to_string("sleep.txt").unwrap();

        //回复客户端
        let responese = format!(
            "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}",
            contents.len(),
            contents
        );
        // let responese ="HTTP/1.1 200 OK\r\n\r\nwanying";
        stream.write(responese.as_bytes()).unwrap();
        stream.flush().unwrap();
    }else{
        //读取文件
        let contents = fs::read_to_string("404.txt").unwrap();

        //回复客户端
        let responese = format!(
            "HTTP/1.1 404 NOT FOUND\r\nContent-Length: {}\r\n\r\n{}",
            contents.len(),
            contents
        );
        // let responese ="HTTP/1.1 200 OK\r\n\r\nwanying";
        // println!("rep:{}",responese);
        stream.write(responese.as_bytes()).unwrap();
        stream.flush().unwrap();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老了希望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值