Rust 如何使用锈迹斑斑的通道将链条螺纹菊花化?

Rust 如何使用锈迹斑斑的通道将链条螺纹菊花化?,rust,coroutine,channels,Rust,Coroutine,Channels,我试图在Rust中实现Eratosthenes的筛选,使用协同程序作为学习练习(而不是家庭作业),但我找不到任何合理的方法将每个线程连接到两个不同通道的接收器和发送器端 接收器涉及两个不同的任务,即报告迄今为止发现的最高素数,并为过滤器提供更多候选素数。这是算法的基础 这是我想做但不能做的,因为接收器不能在线程之间传输。毫不奇怪,使用std::sync::Arc似乎没有帮助 请注意,我确实理解为什么这不起作用 fn main(){ let(basetx,baserx):(发送方,接收方)=信道(

我试图在Rust中实现Eratosthenes的筛选,使用协同程序作为学习练习(而不是家庭作业),但我找不到任何合理的方法将每个线程连接到两个不同通道的
接收器
发送器

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

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

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

fn main(){
let(basetx,baserx):(发送方,接收方)=信道();
设max_数=103;
线程::生成(移动| |{
生成自然数(&basetx,最大数);
});
设oldrx=&baserx;
环路{
//我们需要这个线程中的素数
让prime=match oldrx.recv(){
Ok(num)=>num,
Err()=>{break;0}
};
println!(“{}”,素数);
//以故意未指定的方式创建(newtx,newrx)
//现在我们需要将接收器传递到筛丝上
线程::生成(移动| |{
筛(oldrx,newtx,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)
        }
}
func main(){
通道:=制造(通道内部)
var ok bool=真;
var素数int=0;
去生成(103频道)
真的{

prime,ok=您没有真正解释您遇到的问题,但是您的代码已经足够接近了:

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;
    }
}
使用std::sync::mpsc::{channel,Sender,Receiver};
使用std::线程;
fn生成_编号(发送:发送方){
因为我在2..100{
发送(i).展开();
}
}
fn过滤器(接收端:接收器,发送端:发送器,val:u8){
对于rx中的v{
如果v%val!=0{
发送(v).展开();
}
}
}
fn main(){
let(基_-tx,基_-rx)=信道();
线程::生成(移动| |{
生成_编号(基本_-tx);
});
让mut old_rx=base_rx;
环路{
让num=match old_rx.recv(){
Ok(v)=>v,
错误()=>中断,
};
println!(“素数:{}”,num);
let(新_-tx,新_-rx)=信道();
线程::生成(移动| |{
过滤器(旧的接收、新的发送、数量);
});
旧的接收=新的接收;
}
}
使用协同程序

Danger,Danger,Will Robinson!这些是而不是协同程序;它们是成熟的线程!与协同程序相比,它们要重得多

如果一个
接收者需要交给另一个线程,那么处理这种情况的最佳方法是什么

只是…将
接收器的所有权转移到线程

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