如何使用Rust中的通道菊花链接线程?

时间:2016-03-02 02:17:07

标签: rust coroutine channels

我正在尝试使用协同程序作为学习练习(不是家庭作业)来实现Rust中的Eratosthenes筛,我找不到任何合理的方法将每个线程连接到Receiver和{{1两个不同渠道的结尾。

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

这是我想要做但不能做的事,因为无法在线程之间传输接收器。不出所料,使用Receiver似乎无济于事。

请注意,我确实理解为什么这不起作用

std::sync::Arc

等效工作Go代码:

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;
    }
}

处理这种情况的最佳方法是什么,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) } } 需要传递到另一个线程?

1 个答案:

答案 0 :(得分:3)

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

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的所有权转让给线程?