Rust 中的 Rx in (tx,rx) mpsc::channel 在线程闭包中被丢弃

rx in (tx,rx) mpsc::channel in rust gets dropped in thread closure

提问人:Paul Clements 提问时间:7/29/2023 更新时间:7/29/2023 访问量:62

问:

希望得到一些帮助/建议;我正在尝试向树莓派的 gpio 引脚发送信号。将信号发送到 gpio 引脚是直截了当的,但是通过使用 (tx, rx) = mpsc::channel 发送 meessage 来中断循环来停止在线程中的循环中运行的信号根本不起作用,因为每次闭包返回时都会丢弃 rx,如果这是正确的表达方式的话。Chayim Friedman 非常好心地建议我把通道放在我在这里所做的结构中,让我走上正轨。下面的代码可以编译并运行,但一旦循环开始,rx 仍然会被丢弃。我通过暂时将更改输出替换为连续不变的输出来确认这一点,但 rx 仍然没有响应。谁能帮我解决这个问题?也许 mpsc:channel crate 根本无法胜任这项工作?我正处于一个陡峭的 rust 初始学习曲线上,目的是能够制作自己的 gui 来使用 gui 和 pi gpio 引脚来控制仪器。

use chrono::Utc;
use iced::pure::widget::{Button, Column, Container, Text};
use iced::pure::Sandbox;
use iced::Settings;
use rust_gpiozero::*;
use std::thread;
use std::thread::sleep;
//use std::io::{self, BufRead};
use std::env;
use std::io;
use std::io::BufRead;
use std::process;
use std::sync::mpsc;
use std::sync::mpsc::channel;
use std::time::Duration;
fn main() -> Result<(), iced::Error> {
    Block::run(Settings::default())
}
struct Block {
//tx: SyncSender, 
//tx: mpsc::channel():: u8,
tx: u8,
//rx: u8,
}
#[derive(Debug, Clone, Copy)]
enum CounterMessage {
    Flash1,
    Stop,
}
impl Sandbox for Block {
    type Message = CounterMessage;
    fn new() -> Self {
       Block {
         tx:2,
         //rx:1,
    }
    }
    fn title(&self) -> String {
        String::from("RPi gpio gui")
    }
     fn update(&mut self, message: Self::Message) {
        let  (tx, rx) = channel::<Block>();
        Block {
         tx:2,
         //rx:1,
       };
        match message {
            CounterMessage::Flash1 => {
                //let _ = rx.clone();
                thread::spawn(move||
                    loop {
                    let led = LED::new(17);
                    led.on();
                    sleep(Duration::from_millis(500));
                    led.off();
                    sleep(Duration::from_millis(500));
                    //for received in &rx {
                      // println!("rec ok");
                        //    break;
                          //  } 
                   match rx.try_recv() {
                        Ok(Block{tx: 0_u8..=u8::MAX}) => {
                            println!("rec ok");
                            break;
                         }
                         Err(_recv_error) => {
                            println!("error");
                            continue
                           }
                  }
                 //});
            });  }
            CounterMessage::Stop => {
                    tx.send(Block{ tx: 2_u8 }).unwrap();
                    println!("stop button pressed");
            }
        }
     }
    fn view(&self) -> iced::pure::Element<Self::Message> {
        //let label = Text::new(format!("Count: {}", self.count));
        //let incr = Button::new("Increment").on_press(CounterMessage::Increment);             
        let flash1 = Button::new("FLASH1").on_press(CounterMessage::Flash1);
        let stop = Button::new("STOP FLASH!").on_press(CounterMessage::Stop);
        let col = Column::new()
            .push(flash1)
            .push(stop);
        Container::new(col)
            .center_x()
            .center_y()
            .width(iced::Length::Fill)
            .height(iced::Length::Fill)
            .into()
    }
}

type here

我也尝试过使用crossbeam_channel但遇到了同样的问题。我想知道 rx 被丢弃的问题是不是因为我在非 main() 函数中使用它?我也尝试过克隆 tx,但这不起作用,并且没有克隆 rx 的规定,所以我无法阻止 rx 超出范围。我还尝试将循环放在没有闭包的线程中,以尝试防止 tx 超出范围或被丢弃,但 Rust 不允许这样做,编译器会以所有权问题做出响应。

多线程 闭包通道 丢弃 MPSC

评论


答: 暂无答案