You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tokio开启多个tokio-runtime-w线程是否正常?能否限制?

Tokio开启大量线程是否正常?

先看你提供的top输出:

top - 19:50:25 up  5:55,  2 users,  load average: 0.00, 0.00, 0.00
Threads:   9 total,   0 running,   9 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  19963.7 total,  19046.5 free,    268.3 used,    648.9 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  19449.8 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                                                                                               
   1665 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 nfwd                                                                                                                                                                                                                
   1666 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1667 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1668 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1669 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1670 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1671 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1672 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w                                                                                                                                                                                                       
   1673 root      20   0   17556      4      0 S   0.0   0.0   0:00.00 tokio-runtime-w

你提到仅用tokio::net::UnixListener监听,却出现8个tokio-runtime-w线程,以下是具体分析:

现象原因

这是Tokio的默认行为:当你使用#[tokio::main]注解时,Tokio会自动初始化一个多线程工作池,默认线程数等于你的系统CPU核心数(你看到的8个线程说明你的机器是8核)。这些线程是runtime预创建的,用于处理后续可能的异步任务,哪怕当前只有监听逻辑,runtime也会提前准备好这些资源。

这些线程是否必要?

分场景来看:

  • 对于需要处理大量并发任务(比如多连接处理、CPU密集型异步逻辑)的场景,这些线程是必要的——它们能充分利用多核CPU的并行能力,提升整体吞吐量,同时避免动态创建线程的开销。
  • 如果你的业务逻辑极端简单(比如仅监听一个套接字,没有任何其他并发任务),这些线程属于预分配的闲置资源,此时可以考虑调整。

如何限制或省略这些线程?

你可以通过自定义Tokio runtime来控制线程数量:

1. 使用单线程runtime

如果不需要多线程,直接切换到单线程模式,这样只会产生一个线程:

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn Error>> {    
    let mut stream = StreamServer::new().await?;
    stream.run().await?;
}

2. 自定义多线程runtime的线程数

如果需要多线程但想限制数量,手动创建runtime并指定工作线程数:

use tokio::runtime::Builder;

fn main() -> Result<(), Box<dyn Error>> {
    // 指定工作线程数为2,可根据需求调整
    let runtime = Builder::new_multi_thread()
        .worker_threads(2)
        .build()?;
    
    runtime.block_on(async {
        let mut stream = StreamServer::new().await?;
        stream.run().await?;
        Ok(())
    })
}

额外提示:你的代码bug修正

注意你提供的StreamServer::run方法里有个错误:在Ok((stream, addr))分支中,你误用了self.stream(而self根本没有这个字段),应该用刚接收的stream变量。修正后的代码片段:

pub async fn run(&mut self) -> Result<(), Box<dyn Error>> {
    loop {
        match self.socket.accept().await {
            Ok((mut stream, _addr)) => loop {
                match stream.readable().await {
                    Ok(()) => {
                        let mut buf = Vec::with_capacity(1024);
                        match stream.try_read_buf(&mut buf) {
                            Ok(n) if n > 0 => {
                                let msg = String::from_utf8((&buf[..n]).to_vec())?;
                                println!("收到消息: {}", msg);
                                Ok(())
                            }
                            Ok(_) => Ok(()),
                            Err(ref e) if e.kind() == ErrorKind::WouldBlock => continue,
                            Err(e) => return Err(e.into()),
                        }
                    }
                    Err(e) => return Err(e.into()),
                }
            },
            Err(ref e) if e.kind() == ErrorKind::WouldBlock => continue,
            Err(e) => return Err(e.into()),
        };
    }
}

内容的提问来源于stack exchange,提问作者Nkk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:50:33