首页 > 其他分享 >[Rust] Thread 3: move keyword to resolve borrowing problem for closure

[Rust] Thread 3: move keyword to resolve borrowing problem for closure

时间:2024-03-12 15:48:03浏览次数:32  
标签:closure resolve handle Thread thread move let error

We ofter use movewith closures passed to thread::spawnbecase the closure will then take ownership of the values it uses from the environment, thus transferring owershop of those values from one thread to another.

 

The following code won't work:

use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(|| {
        println!("Here's a vector: {:?}", v);
    });

    handle.join().unwrap();
}

 

We run it, got following error:

$ cargo run
   Compiling threads v0.1.0 (file:///projects/threads)
error[E0373]: closure may outlive the current function, but it borrows `v`, which is owned by the current function
 --> src/main.rs:6:32
  |
6 |     let handle = thread::spawn(|| {
  |                                ^^ may outlive borrowed value `v`
7 |         println!("Here's a vector: {:?}", v);
  |                                           - `v` is borrowed here
  |
note: function requires argument type to outlive `'static`
 --> src/main.rs:6:18
  |
6 |       let handle = thread::spawn(|| {
  |  __________________^
7 | |         println!("Here's a vector: {:?}", v);
8 | |     });
  | |______^
help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword
  |
6 |     let handle = thread::spawn(move || {
  |                                ++++

For more information about this error, try `rustc --explain E0373`.
error: could not compile `threads` due to previous error

Rust infers hwo to capture v, and because println!only needs a reference to v, the closure tries to borrow v. However, there's aproblem: Rust can't tell how long the spawned thread will run, so it doesn't know if the reference v will always be valid.

Why? See following example:

use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(|| {
        println!("Here's a vector: {:?}", v);
    });

    drop(v); // oh no!

    handle.join().unwrap();
}

We call drop(v) in main thread, so the child thread won't be access to v anymore.

 

help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword
  |
6 |     let handle = thread::spawn(move || {
  |                                ++++

 

movekeyword force the clousre to take owership of the values it's using rather than allowing Rust to infer that it should borrow the values.

use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    });

    handle.join().unwrap();
}

 

With the drop example, now it gave different error message:

$ cargo run
   Compiling threads v0.1.0 (file:///projects/threads)
error[E0382]: use of moved value: `v`
  --> src/main.rs:10:10
   |
4  |     let v = vec![1, 2, 3];
   |         - move occurs because `v` has type `Vec<i32>`, which does not implement the `Copy` trait
5  |
6  |     let handle = thread::spawn(move || {
   |                                ------- value moved into closure here
7  |         println!("Here's a vector: {:?}", v);
   |                                           - variable moved due to use in closure
...
10 |     drop(v); // oh no!
   |          ^ value used here after move

For more information about this error, try `rustc --explain E0382`.
error: could not compile `threads` due to previous error

 

标签:closure,resolve,handle,Thread,thread,move,let,error
From: https://www.cnblogs.com/Answer1215/p/18061933

相关文章

  • OpenMP-threadprivate
    threadprivate是OpenMP中的一个指令,用于在多线程环境中为每个线程创建私有变量。通常情况下,OpenMP中的变量默认是共享的,也就是说所有线程都可以访问同一个变量的同一份副本。然而,在某些情况下,需要为每个线程创建独立的变量副本,以避免并发访问问题。threadprivate指令允许程序员将......
  • [Rust] Thread 2: Waiting all thread to finish using join handler
    Codefrompreviousblog:usestd::thread;usestd::time::Duration;fnmain(){thread::spawn(||{foriin1..10{println!("hinumber{}fromthespawnedthread!",i);thread::sleep(Duration::from_millis(1))......
  • [Rust] Intro Thread: 1. Thread with spawn
    Weuse spawntocreateanewthread:usestd::thread;usestd::time::Duration;fnmain(){thread::spawn(||{foriin1..10{println!("hinumber{}fromthespawnedthread!",i);thread::sleep(Duration::from......
  • 并发编程Thread的常用API有哪些?
    引言在JDK17(或以上版本)中,Thread类提供了一组常用的API,用于管理线程的创建、启动、暂停、恢复和销毁等操作。本文从api、源码、编程示例等方面详细说明Thread常用函数的使用和注意事项。线程sleep使当前正在执行的线程暂停(挂起)指定的毫秒数。但受系统计时器和调度程序的精度......
  • RT-THREAD的STM32F4系列移植
    RT-Thread:RT-Thread,全称是RealTime-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务,但允许多个任务同时运行并不意味着处理器在同一时刻真的执行了多个任务。事实上,一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短、任务......
  • spring-HandlerMethodArgumentResolver-参数解析器
    1,参数解析器介绍  HandlerMehtodArgumentResolver,中文成为方法参数解析器,是SpringMvc组件的众多解析器之一,主要用来对Controller的方法参数进行处理。2,参数解析器的使用1,实现HandlerMethodArgumentResolver,自定义解析器publicclassMyHandlerMethodArgumentResolver......
  • TransmittableThreadLocal 的反复与纠缠
    TransmittableThreadLocal相信很多人用过,一个在多线程情况下共享线程上下文的利器名字好长,以下简称ttl本文以两年前一个真实项目开发遇到的问题,从源码的角度分析并解决环境itemversionjava8springboot2.2.2.RELEASEttl2.11.4代码如下,主线程并行启复......
  • springboot3+vue3(四.2)ThreadLocal优化
    解决痛点:我们在拦截器内已经获取并解析了一遍token数据,如图:然后在获取当前登录用户详细信息时又做了一遍同样的操作,如图:后续如果说需要用到当前登录用户的信息时都要带上token参数,这样是很冗余的。这时就会用到ThreadLocal来进行优化处理。 ThreadLocal工具类/***......
  • C++ Qt开发:运用QThread多线程组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QThread组件实现多线程功能。多线程技术在程序开发中尤为常用,Qt框架中提供了QThread库来......
  • Git - error:you need to resolve your current index first 解决方案
    场景:从dev-test分支上拉取dev分支上的代码(意外操作,本应该拉取dev-test分支)相当于从一个分支A,切换到分支B,对B分支进行了pull的操作错误提示:error:youneedtoresolveyourcurrentindexfirst原因:在执行pull操作时,实际是执行了:fetch+merge两个操作。由于分支B很久未......