wordpress网站背景,黄山做网站,百度竞价推广点击软件奔奔,自建商城文章目录 实现异步代码并发地处理连接使用多线程提升性能 使用rust实现一个异步运行时是async-std的单线程Web服务器。 
仓库地址#xff1a; 1037827920/web-server: 使用rust编写的简单web服务器 (github.com) 
在之前的单线程版本的Web服务器代码上进行修改#xff0c;具体… 文章目录 实现异步代码并发地处理连接使用多线程提升性能  使用rust实现一个异步运行时是async-std的单线程Web服务器。 
仓库地址 1037827920/web-server: 使用rust编写的简单web服务器 (github.com) 
在之前的单线程版本的Web服务器代码上进行修改具体代码在给的仓库地址中。 
实现异步代码 
首先将handle_connection修改为async实现 
async fn handle_connection(mut stream: TcpStream) {}该修改会将函数的返回值从()变成FutureOutput  ()因此直接运行将不再有任何效果只用通过.await或执行器的poll。 
使用async-std作为异步运行时 
async-std运行时允许使用属性#[async_std::main]将我们的fn main函数变成async fn main这样就可以在main函数中直接调用其他async函数否则你得用block_on方法来让main去阻塞等待异步函数的完成但是这种简单粗暴的阻塞等待方式并不灵活 
Cargo.toml 
[dependencies]
futures  0.3[dependencies.async-std]
version  1.6
features  [attributes]下面将main函数修改为异步的并在其中调用前面修改的异步版本handle_connection 
use std::{io::{prelude::*, BufReader},net::{TcpListener, TcpStream},fs,time::Duration,
};
extern crate async_std;
use async_std::task;#[async_std::main]
async fn main() {let listener  TcpListener::bind(localhost:8080).unwrap();for stream in listener.incoming() {let stream  stream.unwrap();// 这里还是无法并发handle_connection(stream).await;}
}实现异步版本的handle_connection 
/// # 函数作用
/// 处理连接读取请求回应请求
async fn handle_connection(mut stream: TcpStream) {let buf_reader  BufReader::new(mut stream);// 使用next而不是lines因为我们只需要读取第一行判断具体的request方法let request_line  buf_reader.lines().next().unwrap().unwrap();// 根据请求的不同返回不同的响应let (status_line, filename)  match request_line[..] {GET / HTTP/1.1  (HTTP/1.1 200 OK, hello.html), // 请求 / 资源GET /sleep HTTP/1.1  { // 请求 /sleep 资源// 没有使用std::thread::sleep进行睡眠原因是该函数是阻塞的它会让当前线程陷入睡眠中导致其他任务无法继续运行task::sleep(Duration::from_secs(5)).await;(HTTP/1.1 200 OK, hello.html)}_  (HTTP/1.1 404 NOT FOUND, 404.html),};let contents  fs::read_to_string(filename).unwrap();let length  contents.len();let response  format!({status_line}\r\nContent-Length: {length}\r\n\r\n{contents});// write_all接收[u8]类型作为参数这里需要用as_bytes将字符串转换为字节数组stream.write_all(response.as_bytes()).unwrap();
}可以看出只是把函数变成async往往是不够的还需要将它内部的代码也都变成异步兼容阻塞线程绝对是不可行的 
但是线程web服务器还是不能进行并发处理请求原因是listener.incoming()是阻塞的迭代器。当listener在等待连接时执行器是无法执行其他Future的而且只有当我们处理完已有的连接后才能接收新的连接。 
并发地处理连接 
上面的解决方法是将listener.incoming()从一个阻塞的迭代器变成一个非阻塞的Stream 
use std::{fs,time::Duration,
};
extern crate async_std;
use async_std::{net::{TcpListener, TcpStream},io::{prelude::*, BufReader},task,
};
use futures::StreamExt;#[async_std::main]
async fn main() {let listener  TcpListener::bind(localhost:8080).await.unwrap();listener.incoming().for_each_concurrent(None, |tcpstream| async move {let tpcstream  tcpstream.unwrap();handle_connection(tpcstream).await;}).await;
}异步版本的TcpListener为listener.incoming()实现了Stream trait这样listener.incoming()不再阻塞且使用for_each_concurrent可以并发地处理从Stream获取的元素。 
现在关键在于handle_connection不能再阻塞 
/// # 函数作用
/// 处理连接读取请求回应请求
async fn handle_connection(mut stream: TcpStream) {let buf_reader  BufReader::new(mut stream);// 使用next而不是lines因为我们只需要读取第一行判断具体的request方法let request_line  buf_reader.lines().next().await.unwrap().unwrap();// 根据请求的不同返回不同的响应let (status_line, filename)  match request_line[..] {GET / HTTP/1.1  (HTTP/1.1 200 OK, hello.html), // 请求 / 资源GET /sleep HTTP/1.1  { // 请求 /sleep 资源// 没有使用std::thread::sleep进行睡眠原因是该函数是阻塞的它会让当前线程陷入睡眠中导致其他任务无法继续运行task::sleep(Duration::from_secs(5)).await;(HTTP/1.1 200 OK, hello.html)}_  (HTTP/1.1 404 NOT FOUND, 404.html),};let contents  fs::read_to_string(filename).unwrap();let length  contents.len();let response  format!({status_line}\r\nContent-Length: {length}\r\n\r\n{contents});// write_all接收[u8]类型作为参数这里需要用as_bytes将字符串转换为字节数组stream.write_all(response.as_bytes()).await.unwrap();
}在将数据读写改造成异步后现在该函数也彻底变成了异步版本可以并发地处理连接 
使用多线程提升性能 
async并发和多线程其实并不冲突async-std包也允许我们使用多个线程去处理由于handle_connection实现了Send trait不会阻塞因此使用async_std::task::spawn是非常安全的 
use async_std::task::spawn;#[async_std::main]
async fn main() {let listener  TcpListener::bind(localhost:8080).await.unwarp():listener.incoming().for_each_concurrent(None, |stream| async move {let stream  stream.unwrap();spawn(handle_connection(stream));}).await;
}但是这里是为每个请求都单独创建了一个线程实际上需要限制创建线程的数量可以通过线程池来实现。具体可以看这篇无async的多线程版本的Web服务器 文章转载自: http://www.morning.rxfbf.cn.gov.cn.rxfbf.cn http://www.morning.stwxr.cn.gov.cn.stwxr.cn http://www.morning.phxns.cn.gov.cn.phxns.cn http://www.morning.mqss.cn.gov.cn.mqss.cn http://www.morning.gcspr.cn.gov.cn.gcspr.cn http://www.morning.glrzr.cn.gov.cn.glrzr.cn http://www.morning.kjdxh.cn.gov.cn.kjdxh.cn http://www.morning.skmzm.cn.gov.cn.skmzm.cn http://www.morning.wmhqd.cn.gov.cn.wmhqd.cn http://www.morning.lxhrq.cn.gov.cn.lxhrq.cn http://www.morning.hkgcx.cn.gov.cn.hkgcx.cn http://www.morning.bryyb.cn.gov.cn.bryyb.cn http://www.morning.yrcxg.cn.gov.cn.yrcxg.cn http://www.morning.fbfnk.cn.gov.cn.fbfnk.cn http://www.morning.nfdty.cn.gov.cn.nfdty.cn http://www.morning.mtymb.cn.gov.cn.mtymb.cn http://www.morning.njntp.cn.gov.cn.njntp.cn http://www.morning.qbccg.cn.gov.cn.qbccg.cn http://www.morning.kaylyea.com.gov.cn.kaylyea.com http://www.morning.haibuli.com.gov.cn.haibuli.com http://www.morning.clbzy.cn.gov.cn.clbzy.cn http://www.morning.trlhc.cn.gov.cn.trlhc.cn http://www.morning.qfkxj.cn.gov.cn.qfkxj.cn http://www.morning.dzgmj.cn.gov.cn.dzgmj.cn http://www.morning.pzcqz.cn.gov.cn.pzcqz.cn http://www.morning.hlxxl.cn.gov.cn.hlxxl.cn http://www.morning.slpcl.cn.gov.cn.slpcl.cn http://www.morning.nicetj.com.gov.cn.nicetj.com http://www.morning.nfcxq.cn.gov.cn.nfcxq.cn http://www.morning.rkkh.cn.gov.cn.rkkh.cn http://www.morning.xpzgg.cn.gov.cn.xpzgg.cn http://www.morning.sjwws.cn.gov.cn.sjwws.cn http://www.morning.dlwzm.cn.gov.cn.dlwzm.cn http://www.morning.ydrml.cn.gov.cn.ydrml.cn http://www.morning.qztsq.cn.gov.cn.qztsq.cn http://www.morning.mdmc.cn.gov.cn.mdmc.cn http://www.morning.rcjwl.cn.gov.cn.rcjwl.cn http://www.morning.zryf.cn.gov.cn.zryf.cn http://www.morning.qxxj.cn.gov.cn.qxxj.cn http://www.morning.kkgbs.cn.gov.cn.kkgbs.cn http://www.morning.xnflx.cn.gov.cn.xnflx.cn http://www.morning.ydtdn.cn.gov.cn.ydtdn.cn http://www.morning.cyyhy.cn.gov.cn.cyyhy.cn http://www.morning.qfdyt.cn.gov.cn.qfdyt.cn http://www.morning.kxymr.cn.gov.cn.kxymr.cn http://www.morning.prplf.cn.gov.cn.prplf.cn http://www.morning.mmtbn.cn.gov.cn.mmtbn.cn http://www.morning.rkck.cn.gov.cn.rkck.cn http://www.morning.knczz.cn.gov.cn.knczz.cn http://www.morning.myrmm.cn.gov.cn.myrmm.cn http://www.morning.rbgqn.cn.gov.cn.rbgqn.cn http://www.morning.qnwyf.cn.gov.cn.qnwyf.cn http://www.morning.qflwp.cn.gov.cn.qflwp.cn http://www.morning.qwbht.cn.gov.cn.qwbht.cn http://www.morning.pswzc.cn.gov.cn.pswzc.cn http://www.morning.qrpx.cn.gov.cn.qrpx.cn http://www.morning.mgkb.cn.gov.cn.mgkb.cn http://www.morning.gmjkn.cn.gov.cn.gmjkn.cn http://www.morning.frpfk.cn.gov.cn.frpfk.cn http://www.morning.tjpmf.cn.gov.cn.tjpmf.cn http://www.morning.bdtpd.cn.gov.cn.bdtpd.cn http://www.morning.lxqyf.cn.gov.cn.lxqyf.cn http://www.morning.cwqln.cn.gov.cn.cwqln.cn http://www.morning.gqmhq.cn.gov.cn.gqmhq.cn http://www.morning.cpktd.cn.gov.cn.cpktd.cn http://www.morning.wnjbn.cn.gov.cn.wnjbn.cn http://www.morning.kncrc.cn.gov.cn.kncrc.cn http://www.morning.tbjb.cn.gov.cn.tbjb.cn http://www.morning.jcwrb.cn.gov.cn.jcwrb.cn http://www.morning.gllgf.cn.gov.cn.gllgf.cn http://www.morning.zqkms.cn.gov.cn.zqkms.cn http://www.morning.wjlbb.cn.gov.cn.wjlbb.cn http://www.morning.pqfbk.cn.gov.cn.pqfbk.cn http://www.morning.chfxz.cn.gov.cn.chfxz.cn http://www.morning.ghryk.cn.gov.cn.ghryk.cn http://www.morning.cnvlog.cn.gov.cn.cnvlog.cn http://www.morning.pyxtn.cn.gov.cn.pyxtn.cn http://www.morning.pjrgb.cn.gov.cn.pjrgb.cn http://www.morning.mydgr.cn.gov.cn.mydgr.cn http://www.morning.kqqk.cn.gov.cn.kqqk.cn