【问题标题】:How to daisy chain threads using channels in Rust?如何使用 Rust 中的通道菊花链线程?
【发布时间】:2016-06-14 17:10:15
【问题描述】:

我正在尝试使用协程作为学习练习(不是家庭作业)在 Rust 中实现 Eratosthenes 的筛子,但我找不到任何合理的方法将每个线程连接到 ReceiverSender 的末端两个不同的渠道。

Receiver 涉及两个不同的任务,即报告迄今为止发现的最高素数,并为过滤器提供更多候选素数。这是算法的基础。

这是我想做但不能做的,因为 Receiver 不能在线程之间传输。毫不奇怪,使用 std::sync::Arc 似乎没有帮助。

请注意,我明白为什么这不起作用

fn main() {
    let (basetx, baserx): (Sender<u32>, Receiver<u32>) = channel();
    let max_number = 103;
    thread::spawn(move|| {
        generate_natural_numbers(&basetx, max_number);
    });
    let oldrx = &baserx;
    loop {
        // we need the prime in this thread
        let prime = match oldrx.recv() {
            Ok(num) => num,
            Err(_) => { break; 0 }
        };
        println!("{}",prime);
        // create (newtx, newrx) in a deliberately unspecified way
        // now we need to pass the receiver off to the sieve thread
        thread::spawn(move || {
            sieve(oldrx, newtx, prime); // forwards numbers if not divisible by prime
        });
        oldrx = newrx;
    }
}

等效的工作 Go 代码:

func main() {
        channel := make(chan int)
        var ok bool = true;
        var prime int = 0;
        go generate(channel, 103)
        for true {
                prime, ok = <- channel
                if !ok {
                        break;
                }
                new_channel := make(chan int)
                go sieve(channel, new, prime)
                channel = new_channel
                fmt.Println(prime)
        }
}

Receiver 需要移交给不同线程的这种情况下,最好的方法是什么?

【问题讨论】:

    标签: rust coroutine channels


    【解决方案1】:

    您并没有真正解释您遇到的问题,但您的代码足够接近:

    use std::sync::mpsc::{channel, Sender, Receiver};
    use std::thread;
    
    fn generate_numbers(tx: Sender<u8>) {
        for i in 2..100 {
            tx.send(i).unwrap();
        }
    }
    
    fn filter(rx: Receiver<u8>, tx: Sender<u8>, val: u8) {
        for v in rx {
            if v % val != 0 {
                tx.send(v).unwrap();
            }
        }
    }
    
    fn main() {
        let (base_tx, base_rx) = channel();
        thread::spawn(move || {
            generate_numbers(base_tx);
        });
    
        let mut old_rx = base_rx;
    
        loop {
            let num = match old_rx.recv() {
                Ok(v) => v,
                Err(_) => break,
            };
    
            println!("prime: {}", num);
    
            let (new_tx, new_rx) = channel();
    
            thread::spawn(move || {
                filter(old_rx, new_tx, num);
            });
    
            old_rx = new_rx;
        }
    }
    

    使用协程

    Danger,Danger,Will Robinson!这些是不是协程;它们是成熟的线程!与协程相比,它们的重量级要大得多。

    Receiver 需要移交给不同线程的这种情况下,最好的方法是什么?

    只是...将Receiver 的所有权转移给线程?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      相关资源
      最近更新 更多