首页 > 解决方案 > 为什么功能即使移入新线程也会阻塞

问题描述

我一直在关注指南https://doc.rust-lang.org/book/ch20-02-multithreaded.html#simulating-a-slow-request-in-the-current-server-implementation

该指南指出,对“/sleep”的调用将阻塞,对“/”的调用不会阻塞。但是我不明白为什么对“/ sleep”的其他调用也被阻止了?当然,当每个连接都被移动到一个带有 thread::spawn 的新线程中时,没有理由对 '/sleep' 的 2 次单独调用相互阻塞?线程如何知道调用了哪个端点?

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

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();
}

如果您运行上面的代码并打开几个浏览器选项卡到 localhost:7878,则每个连接都会被阻止,并且必须等待前一个连接解决。

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

标签: rust

解决方案


推荐阅读