英文:
Using a channel to pass message between threads
问题
I need to terminate a loop in a thread in Rust by using (tx, rx) channel in Rust to pass a message to the loop that's running. I have carefully followed chapters 15 -17 of the online rust book to implement a (tx, rx) channel in Rust to terminate a continuously running loop in a thread, but the message won't get through! I am using ICED for the Gui I'm designing and have modified an online ICED example, and it compiles.
英文:
I need to terminate a loop in a thread in Rust by using (tx, rx) channel in Rust to pass a message to the loop that's running. I have carefully followed chapters 15 -17 of the online rust book to implement a (tx, rx) channel in Rust to terminate a continuously running loop in a thread, but the message won't get through! I am using ICED for the Gui I'm designing and have modified an online ICED example, and it compiles.
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::time::Duration;
//fn main() -> Result<(), iced::Error> {
//Counter::run(Settings::default())
//}
fn main() -> Result<(), iced::Error> {
Counter::run(Settings::default())
}
struct Counter {
count: i32,
}
#[derive(Debug, Clone, Copy)]
enum CounterMessage {
Increment,
Decrement,
Increment2,
Decrement2,
Flash1,
Stop,
}
impl Sandbox for Counter {
type Message = CounterMessage;
fn new() -> Self {
Counter { count: 0 }
}
fn title(&self) -> String {
String::from("Counter app")
}
fn update(&mut self, message: Self::Message) {
let (tx, rx) = mpsc::channel();
//let _val = String::from("hi");
match message {
CounterMessage::Increment => self.count += 1,
CounterMessage::Decrement => self.count -= 1,
CounterMessage::Increment2 => self.count += 2,
CounterMessage::Decrement2 => self.count -= 2,
CounterMessage::Flash1 => {
thread::spawn(move || loop {
let led = LED::new(17);
led.on();
sleep(Duration::from_millis(500));
led.off();
sleep(Duration::from_millis(500));
//let r1 = rx.recv().unwrap();
//let r1 = rx.recv();
match rx.recv() {
Ok(_) => {
break;
}
Err(_) => {
println!("error!")
}
}
continue;
//}
});
}
CounterMessage::Stop => {
thread::spawn(move || {
let _val = String::from("hi");
tx.send(_val);
});
}
}
}
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 decr = Button::new("Decrement").on_press(CounterMessage::Decrement);
let incr2 = Button::new("Increment+2").on_press(CounterMessage::Increment2);
let decr2 = Button::new("Decrement-2").on_press(CounterMessage::Decrement2);
let flash1 = Button::new("FLASH1").on_press(CounterMessage::Flash1);
let stop = Button::new("STOP FLASH!").on_press(CounterMessage::Stop);
let col = Column::new()
.push(incr)
.push(label)
.push(decr)
.push(incr2)
.push(decr2)
.push(flash1)
.push(stop);
Container::new(col)
.center_x()
.center_y()
.width(iced::Length::Fill)
.height(iced::Length::Fill)
.into()
}
}
答案1
得分: 1
每次调用update()
时,它都会创建一个新的通道。消息Flash1
的通道和消息Stop
的通道_不是同一个通道_。当你发送到Stop
的通道时,Flash1
的通道不会接收到消息,因为它们没有连接。当我们退出update()
并关闭通道时,Flash1
的发送部分会被丢弃,而Stop
的接收部分也会被丢弃并关闭通道。
您可以将通道存储为Counter
中的字段,这样它就会是同一个通道。一个可能的方式,例如,是存储Option<Sender>
,在调用消息Flash1
时分配给它,在调用消息Stop
时发送到它。
英文:
Every time update()
is called, it creates a new channel. The channels of the message Flash1
and of the message Stop
are just not the same channel. When you send into the channel of Stop
, the channel of Flash1
won't receive the message, because they're not connected. The sender part of Flash1
is dropped when we exit update()
and the channel is closed, and the receiver part of Stop
is also dropped and the channel is closed.
You can store the channel as a field in Counter
, so it will be the same channel. One possibility, for example, is to store Option<Sender>
, assign to it when the message Flash1
is called, and send into it when the message Stop
is called.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论