Rust 为什么即使将函数块移动到新线程中,它仍会被阻塞

Rust 为什么即使将函数块移动到新线程中,它仍会被阻塞,rust,Rust,我一直在跟着导游 该指南指出,对“/sleep”的调用将被阻止,而对“/”的调用将不会被阻止。但是我不明白为什么对“/sleep”的额外呼叫也被阻止了?当然,由于每个连接都使用thread::spawn移动到一个新线程中,所以没有理由对“/sleep”进行两次单独的调用来阻止彼此?线程如何知道正在调用哪个端点 我已经从教程中剥离了代码,我发现如果将thread::sleep行移到stream.read()上方,它将不会阻塞。如果该行位于stream.read()之后,则每个连接似乎位于同一线程上

我一直在跟着导游

该指南指出,对“/sleep”的调用将被阻止,而对“/”的调用将不会被阻止。但是我不明白为什么对“/sleep”的额外呼叫也被阻止了?当然,由于每个连接都使用thread::spawn移动到一个新线程中,所以没有理由对“/sleep”进行两次单独的调用来阻止彼此?线程如何知道正在调用哪个端点

我已经从教程中剥离了代码,我发现如果将thread::sleep行移到stream.read()上方,它将不会阻塞。如果该行位于stream.read()之后,则每个连接似乎位于同一线程上,并且被阻塞,尽管它位于使用thread::spawn()创建的新线程中

如果运行上述代码并打开几个浏览器选项卡以访问localhost:7878,则每个连接都会被阻止,必须等待较早的连接解决


如果将thread::sleep()行移动到stream.read()上方,它将不再阻塞。所以这似乎与stream.read行有关,但我不明白为什么。有人能帮我理解一下吗?

你的代码看起来不错,std.net中出现这样的错误会很奇怪。不过,浏览器的网络线程数量有限。您确定您观察到的限制不是浏览器的限制吗?浏览器似乎不是实现基准服务器并行性的最佳解决方案。谢谢@DenysSéguret,因为您建议通过终端中的curl发出请求,它们看起来是并行运行的。我不知道这是关于浏览器的!文档确实在蓝色框的底部提到了这一点!
use std::io::prelude::*;
use std::net::TcpStream;
use std::net::TcpListener;
use std::thread;
use std::time::Duration;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        thread::spawn(move || {
          handle_connection(stream);
        });
    }
}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 512];

    // thread::sleep(Duration::from_secs(5)); // Doesn't block here (before steam.read())

    stream.read(&mut buffer).unwrap();

    thread::sleep(Duration::from_secs(5)); // Blocks here (after steam.read())

    let response = "HTTP/1.1 200 OK\r\n\r\n";

    stream.write(response.as_bytes()).unwrap();
    stream.flush().unwrap();
}