chunks_exact_mut螺纹寿命

发布于 2025-02-06 19:04:44 字数 926 浏览 1 评论 0原文

以下代码产生有趣的结果:

use std::thread;

fn main() {
    let mut handles = Vec::new();
    let mut v = vec![1, 2, 3, 4];
    
    for x in v.chunks_exact_mut(2) {
        let handle = thread::spawn(move || {
            println!("Here's a vector: {:?}", x);
        });
        
        handles.push(handle);
    }

    for h in handles { h.join().unwrap(); }
}
error[E0597]: `v` does not live long enough
  --> src/main.rs:7:14
   |
7  |     for x in v.chunks_exact_mut(2) {
   |              ^^^^^^^^^^^^^^^^^^^^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
16 | }
   | - `v` dropped here while still borrowed

为什么“块” v更改寿命?如果不“分解” v,代码执行正确。那么,为什么现在会出错呢?

The following code produces interesting results:

use std::thread;

fn main() {
    let mut handles = Vec::new();
    let mut v = vec![1, 2, 3, 4];
    
    for x in v.chunks_exact_mut(2) {
        let handle = thread::spawn(move || {
            println!("Here's a vector: {:?}", x);
        });
        
        handles.push(handle);
    }

    for h in handles { h.join().unwrap(); }
}
error[E0597]: `v` does not live long enough
  --> src/main.rs:7:14
   |
7  |     for x in v.chunks_exact_mut(2) {
   |              ^^^^^^^^^^^^^^^^^^^^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
16 | }
   | - `v` dropped here while still borrowed

Why does 'chunking' v change the lifetime? Without 'chunking' v, the code performs correctly. So why now does it throw an error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情栀口红 2025-02-13 19:04:44

这里的问题在于thread :: Spawn完全将寿命与其余的寿命完全脱离,因为该线程可能会继续运行,而main已经完成。

x是对main中变量的引用,并且不能保证main寿命比线程更长。

我认为您真正想要的是一个螺纹助手库,例如 rayon ,由于他们已经在内部解决了这些问题:

use rayon::prelude::*;

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

    v.par_chunks_exact_mut(2).for_each(|x: &mut [i32]| {
        let thread_id = std::thread::current().id();
        println!("{:?}: Here's a vector: {:?}", thread_id, x);
    });
}
ThreadId(5): Here's a vector: [1, 2]
ThreadId(2): Here's a vector: [3, 4]

The problem here is that thread::spawn completely decouples the lifetime from the rest, as the thread might continue to run while main is already finished.

x is a reference to a variable in main, and there is no guarantee that main lives longer than the thread.

I think what you really want here is a threading helper library like rayon, as they already solve those problems internally:

use rayon::prelude::*;

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

    v.par_chunks_exact_mut(2).for_each(|x: &mut [i32]| {
        let thread_id = std::thread::current().id();
        println!("{:?}: Here's a vector: {:?}", thread_id, x);
    });
}
ThreadId(5): Here's a vector: [1, 2]
ThreadId(2): Here's a vector: [3, 4]
甜点 2025-02-13 19:04:44

如果不“块” v,您正在迭代vec< i32>。此迭代器生成类型i32的项目,因此,无参考,没有终生,thread :: spawn()(特别是'static) >要求)。

chunks_exact_mut(),但是,是在切片上定义的,并通过& mut [t]赋予迭代器,因此它具有参考。并且由于此引用引用v,它存在于main()中,因此它不是'static,并且不起作用。

如果您可以通过& v而不是v迭代,则可以观察到相同的问题,因为该迭代器给您& i32 s(

error[E0597]: `v` does not live long enough
  --> src/main.rs:7:14
   |
7  |     for x in &v {
   |              ^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
16 | }
   | - `v` dropped here while still borrowed

;那就是我建议使用rayon如@finomnis所建议的。

Without "chunking" v, you're iterating over Vec<i32>. This iterator produces items of type i32, so, no references, no lifetimes, the requirements for thread::spawn() (specifically the 'static requirement) are met.

chunks_exact_mut(), however, is defined on slices and gives iterator over &mut [T], so it does have a reference. And since this reference refers v, which exists in main(), it is not 'static and does not work.

You can observe the same problem if you'll iterate over &v instead of v, since that iterator gives you &i32s (playground):

error[E0597]: `v` does not live long enough
  --> src/main.rs:7:14
   |
7  |     for x in &v {
   |              ^^
   |              |
   |              borrowed value does not live long enough
   |              argument requires that `v` is borrowed for `'static`
...
16 | }
   | - `v` dropped here while still borrowed

Other than that, I'd recommend using rayon as @Finomnis suggested.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文