BBCCBB
V2EX  ›  Rust

[Rust] 为啥我这里的 p 可以在多个线程间转移所有权并使用呢?

  •  
  •   BBCCBB · May 18, 2022 · 2914 views
    This topic created in 1630 days ago, the information mentioned may be changed or developed.
    
    
    use std::thread;
    
    fn main() {
        struct Point<T> {
            pub x: T,
        }
    
        let mut p = Point { x: 32 };
        
    
        let mut vals = Vec::new();
        for _ in 0..2 {
            let h = thread::spawn(move || {
                p.x = 5;
                println!("{}", p.x);
            });
            vals.push(h);
        }
    
        for v in vals {
            v.join().unwrap();
        }
        println!("{}", p.x);  // 32
    }
    
    输出结果是两个 5 和最后的 32, 也就是说线程里修改对主线程无效
    

    playground url: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bf8936b4cc64c1f3124e926e81d9b4d6

    DDDD -_-

    我这里的变量 p 为啥能在多个线程间修改和使用呢? 懂的兄弟带带我, 谢谢.

    同时求一个好的 rust 社区 /论坛 /讨论区

    13 replies  •  2022-05-19 11:04:06 +08:00
    reter
    reter
    May 18, 2022❤️1
    1
    我分析,编译器认为只有 p.x 被移动,然后 p.x 默认是 i32 类型, 自动实现了 Copy, 所以在 move 闭包下,创建了新的变量, 复制了 p.x 的值。

    如果 p 里面有其它不可移动的字段,然后在 move 闭包里面 进行了操作,那么无法通过编译。


    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a93e02138c3df6841f402b0ccbb7d7be
    BBCCBB
    BBCCBB
    OP
    May 18, 2022
    2
    @reter 有道理, 我再回去好好看看多线程这里. 多谢, 这些小坑烧脑壳
    liuhan907
    liuhan907
    May 18, 2022
    3
    @BBCCBB
    你的 p 的具体类型 Point<i32> 字段全满足 Sync ,所以 Point<i32> 也自动满足 Sync ,因此跨线程共享是安全的。你可以尝试用 Point<String> 试试看。
    BBCCBB
    BBCCBB
    OP
    May 18, 2022
    4
    @liuhan907 对的, 我也试过这个..

    ```rust
    fn isSync<T: Sync>(_: &T) {}
    isSync(&p);
    ```
    我再去仔细看下 Sync/Send, 多谢.
    BBCCBB
    BBCCBB
    OP
    May 18, 2022
    5
    @liuhan907 还有就是我明确使用 move. 但 p 所有权并没有转进去.==
    liuhan907
    liuhan907
    May 18, 2022
    6
    @BBCCBB
    和别人交流了一下,这个就是部分捕获。实际上被 move 的是单独的那个 x , @reter 老哥就是对的。
    BBCCBB
    BBCCBB
    OP
    May 18, 2022
    7
    @liuhan907 大佬有这方面的文档吗? 以后出了问题我好去翻翻,, 还有就是有啥 rust 论坛吗, dddd
    mr0joker
    mr0joker
    May 18, 2022 via iPhone
    8
    rust 官网不就有个交流的地方
    https://users.rust-lang.org/
    mr0joker
    mr0joker
    May 18, 2022 via iPhone
    9
    接 8 楼,个人认为那个网站是“好的”
    Buges
    Buges
    May 19, 2022 via Android❤️1
    10
    这是 rust 2021 edition 的新特性 https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html
    move 的只有 x ,而 x 实现了 Copy 。
    BBCCBB
    BBCCBB
    OP
    May 19, 2022
    11
    @mr0joker 多谢多谢.
    @Buges 牛逼, 有理有据,令人信服
    reter
    reter
    May 19, 2022
    12
    我只知道 struct 可以只 move 部分字段,在闭包里还没见过部分捕获。


    论坛的话,https://rustcc.cn/ 也不错,rustdesk 也在这个论坛上活跃
    BBCCBB
    BBCCBB
    OP
    May 19, 2022
    13
    @reter 感谢, 10 楼链接里就是原理了... 新特性,哈哈, 不是 Copy, 是 disjoint capture
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1684 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 17:12 · PVG 01:12 · LAX 09:12 · JFK 12:12
    ♥ Do have faith in what you're doing.