Rust std::thread::spawn(move) 的作用

rust 复制代码
    for ip in ip_list {
        let s1 = sem.clone();
        let d1 = done_snd.clone();
        let o1 = opt.clone();
        // async move   move 
        std::thread::spawn(move || {
            let rt = tokio::runtime::Runtime::new().unwrap();
            rt.block_on(async {
                let sem = s1.acquire_owned().await.unwrap();
                info!("try to path {ip}");
                match process_host_with_retry(&o1, &ip).await {
                    Ok(_) => d1.send(WriteMsg::Ok(ip.to_string())).await.unwrap(),
                    Err(e) => {
                        warn!("patch {ip} failed, {e}");
                        d1.send(WriteMsg::Err(ip.to_string())).await.unwrap()
                    }
                }

                drop(sem);
            });
        });
    } 

围观大佬于写代码。出现这个问题。写的时候带了 async 就无法执行了。搜索了一下:

原因:

async 关键字把代码块变成了一个 Future ,它不会在创建时立即执行,而是要等到被 poll/await 才会真正跑起来;而 std::thread::spawn 期待的是一个立刻就会在新线程里 同步执行 的函数体 (FnOnce() -> T)。
一句话 :把 async 放到 move 前后,只是生成了一个 future;如果你不在同一个线程里 await/block_on 它,逻辑就永远不会被调度

去掉 async,闭包又变回同步函数体,线程启动后就直接执行!!!

关键点回顾

  1. async 块 ≠ 立即执行 :它只是"构建"一个状态机,真正运行发生在 .await/poll。

  2. std::thread::spawn 只能执行同步闭包------要么在闭包里 block_on,要么别用它。

  3. Tokio runtime 已经能并发调度 future,通常不需要再额外开 OS 线程。

相关推荐
鶴哥只手遮天13 小时前
《Redis 8.10.3 深度剖析》系列 · 第 1 章·全景与源码地图:版本谱系、构建体系、全局状态与启动链路
redis·后端·开源
用户4003150433513 小时前
《从 skynet.timeout 到回调执行:Skynet 分层时间轮源码剖析》
后端
一条Go13 小时前
四个进程,一把锁:Alioth 的告警评测为什么不需要消息队列
后端·设计模式·架构
用户19961435599613 小时前
插件是怎么被安全装进系统的
后端
Pniubi13 小时前
Java为什么要分堆和栈
java·开发语言
愚农搬码14 小时前
自研表单引擎、开源组件二开和商业产品,企业应该如何选择?
后端
用户2986985301414 小时前
Python 自动化处理 Word 页眉页脚的几种典型场景
后端·python·api
小小晓.14 小时前
Qt 对话框、QLineEdit 与布局管理实战详解
开发语言·qt
愚农搬码14 小时前
一款企业级电子表单系统应该具备哪些功能?
后端
炸薯条!14 小时前
博客系统测试报告
开发语言·lua