【问题标题】:How to pass a PrimInt to multiple threads?如何将 PrimInt 传递给多个线程?
【发布时间】:2019-06-20 18:50:57
【问题描述】:

我想编写一个接受整数的函数,并生成使用该整数的线程。可以计算整数。它不需要是文字。如果我使用具体类型,例如usize,它会起作用,但是当我尝试概括它时,它会fails to compile

fn g<A>(a: A)
where
    A: num::PrimInt + Copy + std::fmt::Debug + Send,
{
    let hs = (0..3).map(|_| {
        std::thread::spawn(move || {
            println!("{:?}", a);
        })
    });

    for h in hs {
        h.join().unwrap();
    }
}

错误是:

1 | fn g<A>(a: A)
  |      - help: consider adding an explicit lifetime bound `A: 'static`...
...
6 |         std::thread::spawn(move || {
  |         ^^^^^^^^^^^^^^^^^^
  |
note: ...so that the type `[closure@src/main.rs:6:28: 8:10 a:A]` will meet its required lifetime bounds
 --> src/main.rs:6:9
  |
6 |         std::thread::spawn(move || {
  |         ^^^^^^^^^^^^^^^^^^

由于我具有Copy 特征,它应该能够为每个线程复制此值,因此不需要生命周期限制建议。我该如何解决这个问题?

【问题讨论】:

  • 这个建议必要的。考虑到所有不可变引用都是Copy,无论它们的生命周期如何。
  • @Michail 什么参考?它是一个整数,我想为每个线程制作一个副本。
  • 是的,但是引用类型有朝一日可能会实现PrimInt,并且编译器会对此进行防范。
  • @Michail 这没有任何意义。 Copy 的目的是表明该值可以被复制。
  • 我真的不擅长解释事情,所以这里有一个提供信息解释的问题:here 类似情况。

标签: multithreading generics rust


【解决方案1】:

Copy'static 是不同的约束条件,两者 都是跨线程移动值所必需的。虽然您可能只打算将整数(同时满足 Copy'static)传递给您的泛型函数,但编译器无法确定。它必须能够证明函数体对于所有可能的类型参数都是有效的。 Copy 但不是 'static 的类型示例是 reference to a local variable

fn assert_is_copy<T: Copy>(_: T) {}
fn assert_is_static<T: 'static>(_: T) {}

fn main() {
    let x: usize = 5;

    assert_is_copy(x);
    assert_is_static(x);
    assert_is_copy(&x);
    //assert_is_static(&x); // FAILS TO COMPILE
}

我想你会同意你不想将你的堆栈变量的引用传递给不同的线程(尽管它在some limited cases 中是安全的)。如果你这样做了,你可以分离那个线程,弹出带有局部变量的堆栈帧,并导致未定义的行为!

This answerT: 'static 的含义给出了一个简单、(大部分)正确的解释。

【讨论】:

    【解决方案2】:

    其他人已经解释了为什么您的代码不起作用,但如果您仍然想如何让它起作用,只需将+ 'static 添加到您的约束中:

    fn g<A>(a: A)
    where
        A: num::PrimInt + Copy + std::fmt::Debug + Send + 'static,
    {
        let hs = (0..3).map(|_| {
            std::thread::spawn(move || {
                println!("{:?}", a);
            })
        });
    
        for h in hs {
            h.join().unwrap();
        }
    }
    

    【讨论】:

    • 正如我在原始问题中所说,整数可以计算出来,而不是文字。 'static 不适用于我的用例。
    【解决方案3】:

    根据其他答案对我的问题的直接答案如下:

    在 Rust 中,不可能将计算得出的非文字 PrimInt 传递给多个线程。

    【讨论】:

    • 这是错误的。所有原始整数类型(例如u32isize)都是'static。它们来自文字还是在运行时计算并不重要。
    • 您需要做的就是遵循编译器的建议(添加绑定到A'static),然后将任何整数值传递给g
    猜你喜欢
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2012-01-07
    • 1970-01-01
    • 2020-11-26
    相关资源
    最近更新 更多