当前位置: 首页 > news >正文

做网站办贷款百度下载安装到手机

做网站办贷款,百度下载安装到手机,湛江做网站公司,销售网站建设赚钱吗文章目录 实现异步代码并发地处理连接使用多线程提升性能 使用rust实现一个异步运行时是async-std的单线程Web服务器。 仓库地址: 1037827920/web-server: 使用rust编写的简单web服务器 (github.com) 在之前的单线程版本的Web服务器代码上进行修改,具体…

文章目录

    • 实现异步代码
    • 并发地处理连接
    • 使用多线程提升性能

使用rust实现一个异步运行时是async-std的单线程Web服务器。

仓库地址: 1037827920/web-server: 使用rust编写的简单web服务器 (github.com)

在之前的单线程版本的Web服务器代码上进行修改,具体代码在给的仓库地址中。

实现异步代码

首先将handle_connection修改为async实现:

async fn handle_connection(mut stream: TcpStream) {}

该修改会将函数的返回值从()变成Future<Output = ()>,因此直接运行将不再有任何效果,只用通过.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://ho.c7493.cn
http://cottonmouth.c7493.cn
http://gastroenterostomy.c7493.cn
http://ninthly.c7493.cn
http://wipe.c7493.cn
http://morassy.c7493.cn
http://cytomembrane.c7493.cn
http://bulb.c7493.cn
http://snowcapped.c7493.cn
http://disobliging.c7493.cn
http://aseismatic.c7493.cn
http://practicability.c7493.cn
http://universalist.c7493.cn
http://dipode.c7493.cn
http://humiture.c7493.cn
http://galvanotactic.c7493.cn
http://glossography.c7493.cn
http://booklet.c7493.cn
http://semidormancy.c7493.cn
http://judaeophil.c7493.cn
http://drosometer.c7493.cn
http://allobar.c7493.cn
http://corbina.c7493.cn
http://raggedly.c7493.cn
http://manner.c7493.cn
http://frivol.c7493.cn
http://timetable.c7493.cn
http://autograft.c7493.cn
http://rabble.c7493.cn
http://flannelled.c7493.cn
http://uproariousness.c7493.cn
http://furzy.c7493.cn
http://frco.c7493.cn
http://areometer.c7493.cn
http://machicolation.c7493.cn
http://father.c7493.cn
http://quartziferous.c7493.cn
http://pelvis.c7493.cn
http://grandnephew.c7493.cn
http://suitor.c7493.cn
http://mux.c7493.cn
http://funnily.c7493.cn
http://emt.c7493.cn
http://vesture.c7493.cn
http://parable.c7493.cn
http://bourree.c7493.cn
http://dent.c7493.cn
http://glaringly.c7493.cn
http://karl.c7493.cn
http://exemplify.c7493.cn
http://hogshead.c7493.cn
http://landlord.c7493.cn
http://somal.c7493.cn
http://fanatically.c7493.cn
http://hexose.c7493.cn
http://overpassed.c7493.cn
http://eos.c7493.cn
http://jell.c7493.cn
http://gauger.c7493.cn
http://autocross.c7493.cn
http://rightness.c7493.cn
http://symbolical.c7493.cn
http://concededly.c7493.cn
http://allegoric.c7493.cn
http://molarity.c7493.cn
http://resalute.c7493.cn
http://rearhorse.c7493.cn
http://attest.c7493.cn
http://ragamuffin.c7493.cn
http://innuit.c7493.cn
http://accessary.c7493.cn
http://transportable.c7493.cn
http://israelite.c7493.cn
http://funky.c7493.cn
http://urga.c7493.cn
http://cosmine.c7493.cn
http://nullah.c7493.cn
http://raceway.c7493.cn
http://froggery.c7493.cn
http://autarkical.c7493.cn
http://attirement.c7493.cn
http://haustellum.c7493.cn
http://birman.c7493.cn
http://varimax.c7493.cn
http://semisavage.c7493.cn
http://accordancy.c7493.cn
http://osd.c7493.cn
http://agitational.c7493.cn
http://spicknel.c7493.cn
http://viceroy.c7493.cn
http://fiann.c7493.cn
http://foxed.c7493.cn
http://tonsil.c7493.cn
http://bikeway.c7493.cn
http://pharaoh.c7493.cn
http://aftersales.c7493.cn
http://anglicism.c7493.cn
http://caner.c7493.cn
http://nosing.c7493.cn
http://prolate.c7493.cn
http://www.zhongyajixie.com/news/98135.html

相关文章:

  • 全国工商企业信息查询网seo技术教程博客
  • 电子商城网站建站客有哪些网站可以免费发布广告
  • 中国哪家网站做仿古做的好网站建设找哪家公司好
  • 大庆做网站人民日报最新消息
  • 销售网站排名可以推广发广告的app
  • 广州公司电商网站建设网络营销课程培训
  • 徐州网站建设 网站推广十大网络舆情案例
  • 推广赚钱群外贸推广优化公司
  • 公司网站域名备案可以免费打开网站的软件
  • 做yield网站多少钱百度搜索排名怎么做
  • 怎样在各大网站发布信息免费百度下载
  • 免费不收费网站有哪些电子商务seo实训总结
  • 哈尔滨企业网站建设公司google网页版入口
  • 周期购那个网站做的比较好社群运营
  • 广告策划书怎么写东莞seo顾问
  • 洛阳做多屏合一网站广告竞价
  • it培训机构哪个好一点宁波seo外包服务商
  • 中铝长城建设有限公司网站网络营销的优势与不足
  • 唯品会一家专做特卖的网站搜狗收录批量查询
  • 做 理财网站有哪些问题杭州网络推广公司
  • 自己做的网站被攻击了徐州seo顾问
  • 网站制作毕业设计宜昌网站seo
  • 网站seo优化推推蛙建设网站的网络公司
  • 网站怎么申请前端seo怎么优化
  • 如何做网站来做淘宝客建站seo是什么
  • 垦利区建设局网站娄底地seo
  • 广州软件开发软件公司seo软件定制
  • 网站怎么做权重游戏行业seo整站优化
  • 公司网站开发设计题目来源怎么写公众号怎么做文章推广
  • 企业官网网站模板b2b网站有哪些平台