Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 使用tokio spawn,速度与单线程一样快,这是tokio spawn的正确方式_Asynchronous_Rust_Tokio - Fatal编程技术网

Asynchronous 使用tokio spawn,速度与单线程一样快,这是tokio spawn的正确方式

Asynchronous 使用tokio spawn,速度与单线程一样快,这是tokio spawn的正确方式,asynchronous,rust,tokio,Asynchronous,Rust,Tokio,我想写一个关于如何像蜘蛛一样访问互联网的程序。我使用了tokio::spawn来让每个url在运行时都是异步的。当我在循环中使用tokio reqwest时,这似乎与单个线程的过程相同。Rust async与js不同。我不太明白它是如何工作的。我已经考虑了很多天了。我问公众,这是密码 use tokio::task; use scraper::{Html, Selector}; use url::Url; #[tokio::main] async fn main() { let mut

我想写一个关于如何像蜘蛛一样访问互联网的程序。我使用了tokio::spawn来让每个url在运行时都是异步的。当我在循环中使用tokio reqwest时,这似乎与单个线程的过程相同。Rust async与js不同。我不太明白它是如何工作的。我已经考虑了很多天了。我问公众,这是密码

use tokio::task;
use scraper::{Html, Selector};
use url::Url;
#[tokio::main]
async fn main() {
    let mut visited_url:Vec<String> = Vec::new();
    let mut visiting_url:Vec<String> = Vec::new();
    
    visiting_url.push("https://baike.baidu.com/".to_string());

    let client = reqwest::Client::builder()
                        .user_agent("ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36")
                        .build().unwrap();
    let fut = tokio::spawn(async move {
        loop{
            let cclient = &client;
            let main_url = visiting_url.pop().unwrap();
            println!("{}",main_url);
            visited_url.push(main_url.clone());
            let resp = cclient.get(&main_url).send().await.unwrap();
            let status_code = resp.status().as_u16();
            let html = resp.text().await.unwrap();

            let document = Html::parse_document(&html);
            for element in document.select(&Selector::parse("[href]").unwrap()) {
                let href = element.value().attr("href").unwrap();
                let abs_url = Url::parse(&main_url).unwrap().join(href).unwrap().as_str().to_string();
                if !visited_url.contains(&abs_url) {
                    visiting_url.push(abs_url);
                }
            }
            println!("{}",status_code);
        }
        // task::yield_now().await;
    });
    task::unconstrained(fut).await;
}
我这样修改代码,但是速度的提高还是很小的

use reqwest::Client;
use tokio::task;
use scraper::{Html, Selector};
use url::Url;
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;

lazy_static! {
    static ref visited_url: Mutex<Vec<String>> = Mutex::new(vec![]);
    static ref visiting_url: Mutex<Vec<String>> = Mutex::new(vec![]);
}

async fn get(client: &Client){
    let main_url = visiting_url.lock().unwrap().pop().unwrap();
    println!("{}",main_url);
    visited_url.lock().unwrap().push(main_url.clone());
    let resp = client.get(&main_url).send().await.unwrap();
    let status_code = resp.status().as_u16();
    let html = resp.text().await.unwrap();

    let document = Html::parse_document(&html);
    for element in document.select(&Selector::parse("[href]").unwrap()) {
        let href = element.value().attr("href").unwrap();
        let abs_url = Url::parse(&main_url).unwrap().join(href).unwrap().as_str().to_string();
        if !visited_url.lock().unwrap().contains(&abs_url) {
            visiting_url.lock().unwrap().push(abs_url);
        }
    }
    println!("{}",status_code);
}

#[tokio::main]
async fn main() {
    
    visiting_url.lock().unwrap().push("https://baike.baidu.com/".to_string());

    let client = reqwest::Client::builder()
                        .user_agent("ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36")
                        .build().unwrap();
    loop{
        // get(&client).await;
        tokio::spawn(get(client.clone()));
    }
}

使用reqwest::客户端;
使用tokio::task;
使用scraper::{Html,Selector};
使用url::url;
#[宏_使用]
外部板条箱(静态);
使用std::sync::Mutex;
懒惰的人!{
静态引用访问\u url:Mutex=Mutex::new(vec![]);
静态引用访问url:Mutex=Mutex::new(vec![]);
}
异步fn get(客户端:&客户端){
让main_url=访问_url.lock().unwrap().pop().unwrap();
println!(“{}”,主url);
已访问_url.lock().unwrap().push(main_url.clone());
让resp=client.get(&main_url).send().wait.unwrap();
将status_code=resp.status()设为_u16();
让html=resp.text().wait.unwrap();
let document=Html::parse_document(&Html);
对于文档中的元素。选择(&选择器::解析(“[href]”)。展开(){
让href=element.value().attr(“href”).unwrap();
让abs_url=url::parse(&main_url).unwrap().join(href).unwrap().as_str().to_string();
if!已访问\u url.lock().unwrap()包含(&abs\u url){
访问_url.lock().unwrap().push(abs_url);
}
}
println!(“{}”,状态代码);
}
#[tokio::main]
异步fn main(){
正在访问_url.lock().unwrap().push(“https://baike.baidu.com/“.to_string());
让client=reqwest::client::builder()
.user_agent(“ozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如Gecko)Chrome/89.0.4389.114 Safari/537.36”)
.build().unwrap();
环路{
//获取(&客户机)。等待;
tokio::spawn(get(client.clone());
}
}
use reqwest::Client;
use tokio::task;
use scraper::{Html, Selector};
use url::Url;
#[macro_use]
extern crate lazy_static;
use std::sync::Mutex;

lazy_static! {
    static ref visited_url: Mutex<Vec<String>> = Mutex::new(vec![]);
    static ref visiting_url: Mutex<Vec<String>> = Mutex::new(vec![]);
}

async fn get(client: &Client){
    let main_url = visiting_url.lock().unwrap().pop().unwrap();
    println!("{}",main_url);
    visited_url.lock().unwrap().push(main_url.clone());
    let resp = client.get(&main_url).send().await.unwrap();
    let status_code = resp.status().as_u16();
    let html = resp.text().await.unwrap();

    let document = Html::parse_document(&html);
    for element in document.select(&Selector::parse("[href]").unwrap()) {
        let href = element.value().attr("href").unwrap();
        let abs_url = Url::parse(&main_url).unwrap().join(href).unwrap().as_str().to_string();
        if !visited_url.lock().unwrap().contains(&abs_url) {
            visiting_url.lock().unwrap().push(abs_url);
        }
    }
    println!("{}",status_code);
}

#[tokio::main]
async fn main() {
    
    visiting_url.lock().unwrap().push("https://baike.baidu.com/".to_string());

    let client = reqwest::Client::builder()
                        .user_agent("ozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36")
                        .build().unwrap();
    loop{
        // get(&client).await;
        tokio::spawn(get(client.clone()));
    }
}