如何将PrimInt传递给多个线程?

时间:2019-06-20 18:50:57

标签: multithreading generics rust

我想编写一个接受整数的函数,并生成使用该整数的线程。可以计算整数。它不必是文字。如果我使用诸如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特质,因此它应该能够为每个线程复制该值,因此不需要使用期限限制的建议。我该如何解决?

3 个答案:

答案 0 :(得分:1)

Copy'static是不同的约束,并且两者都是在线程之间移动值所必需的。尽管您可能只打算将整数(同时满足Copy'static的情况)传递给泛型函数,但编译器无法确定。必须能够证明该功能主体对所有可能的类型参数有效。 reference to a local variableCopy但不是'static的类型的示例:

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 answer对说T: 'static的含义给出了一个简单(大部分)正确的解释。

答案 1 :(得分:1)

其他人解释了为什么您的代码不起作用,但是如果您仍然想知道如何使其工作,只需在您的代码中添加+ '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();
    }
}

答案 2 :(得分:0)

基于其他答案,我的问题的直接答案如下:

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