一个线程可以移动到另一个线程中吗?

问题描述 投票:0回答:1
use std::collections::VecDeque;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
fn main() {
    let queue = Arc::new(Mutex::new(VecDeque::new())); //because of the move keyword to move the thread t into the
    let q_clone = queue.clone();
    thread::scope(move |s| {
        //let q_cl = queue
        let t = s.spawn(move || loop {
            let item = queue.lock().unwrap().pop_front();
            if let Some(item) = item {
                dbg!(item);
            } else {
                thread::park();
            }
        });
        s.spawn(move || {
            for i in 1.. {
                q_clone.lock().unwrap().push_back(i);
                t.thread().unpark();
                thread::sleep(Duration::from_secs(1));
            }
        });
    });
}

在第二个线程spawn中,使用了

move
关键字 我有两个问题:

  1. 根据我的理解,
    Arc
    发生了什么,
    Arc
    提供了一个引用,克隆它只会增加引用计数,所以根据我的说法,引用只需要借用,不需要取得所有权,但是删除移动时会出现错误。
  2. 在第二个线程生成时,线程
    t
    是否移动到另一个线程中,如果不是,这如何确保线程
    t
    的生命周期小于第二个线程的生命周期。
multithreading rust thread-safety
1个回答
0
投票

线程不是可以移动的值,

spawn
只给你一个
ScopedJoinHandle
,通过它你可以与线程交互。无法保证任何一个线程的寿命都比另一个线程长。

这里的错误与

Arc
根本无关,事实上你也不需要它,但是因为你传递给
thread::scope()
的闭包是在你的线程之前运行的,因此
t
是它本地的当第二个线程闭包未标记
move
时超出范围,因此这段代码:

use std::collections::VecDeque;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
fn main() {
    let queue = &Mutex::new(VecDeque::new());
    thread::scope(|s| {
        let t = s.spawn(|| loop {
            let item = queue.lock().unwrap().pop_front();
            if let Some(item) = item {
                dbg!(item);
            } else {
                thread::park();
            }
        });
        s.spawn(move || {
            for i in 1.. {
                queue.lock().unwrap().push_back(i);
                t.thread().unpark();
                thread::sleep(Duration::from_secs(1));
            }
        });
    });
}

确实按照您的预期工作,第二个闭包再次需要

move
,因为否则
t
在使用之前就会被删除。

© www.soinside.com 2019 - 2024. All rights reserved.