在线程下移动 Arc Mutex Ncurses window 仍然没有实现发送
Moving Arc Mutex Ncurses window down thread still doesn't implement send
我正在为我正在做的一件小事构建一个 ncurses 界面。对于输入,我想非阻塞地读取它。我想我可以将 WINDOW 包装在 Arc Mutex 中,但这似乎不起作用,因为它仍然抱怨发送。这是因为ncurses的实现不安全吗?我该如何解决这个问题?理想情况下,我会使用回调而不是 tx 来完成这项工作,这样我就可以从堆栈的视图中删除依赖性,但我也无法将闭包发送给 Send。
我正在使用这个库:https://github.com/jeaye/ncurses-rs
简化代码:
pub struct View {
max_x: i32,
max_y: i32,
messages_window: WINDOW,
input_window: Arc<Mutex<WINDOW>>
}
pub fn init(&mut self, input_tx: mpsc::Sender<DispatchMessage>) {
let input_window = self.input_window.clone();
thread::spawn(move || {
loop {
let input_window = input_window.lock().unwrap();
draw_prompt(input_window);
let input = prompt_input(input_window);
input_tx.send(input_to_message(input)).unwrap();
}
});
}
fn prompt_input(input: WINDOW) -> String {
let mut string = String::new();
wgetstr(input, &mut string);
string
}
fn draw_prompt(input: WINDOW) {
wclear(input);
let top = 0 as chtype;
let bottom = ' ' as chtype;
let empty = ' ' as chtype;
wborder(input, empty,empty,top,bottom,empty,empty,empty,empty);
mvwprintw(input, 1, 1, ">> ");
wrefresh(input);
}
我得到的错误:
src/view.rs:40:33: 40:45 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:40 draw_prompt(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:40:33: 40:45 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:41:46: 41:58 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:41 let input = prompt_input(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:41:46: 41:58 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:37:13: 37:26 error: the trait `core::marker::Send` is not implemented for the type `*mut ncurses::ll::WINDOW_impl` [E0277]
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
src/view.rs:37:13: 37:26 note: `*mut ncurses::ll::WINDOW_impl` cannot be sent between threads safely
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
error: aborting due to 3 previous errors
手动解除对 window 的引用可以消除类型错误,但我认为我会保留它,因为它可能表明出了什么问题。
Arc<T>
实现了 Send
,其中 T
实现了 Send
和 Sync
。 Mutex<T>
实现 Send
和 Sync
,其中 T
实现 Send
。所以 Arc<Mutex<T>>
仅在 T
实现 Send
时才实现 Send
。请记住,Send
表示“能够跨线程边界传输的类型”。 Arc<Mutex<T>>
允许从多个线程访问它的内容,纯粹处理所有权和可变性问题,所以如果底层类型不能跨线程边界传输,它也无济于事。您可能需要从一个线程执行所有 ncurses 操作。
Raw pointers 明确不实施 Send
因为无法保证它。您可以在其之上构造显式实现 Send
的类型,从而保证所包含的原始指针实际上对于跨线程边界传输是安全的。
我正在为我正在做的一件小事构建一个 ncurses 界面。对于输入,我想非阻塞地读取它。我想我可以将 WINDOW 包装在 Arc Mutex 中,但这似乎不起作用,因为它仍然抱怨发送。这是因为ncurses的实现不安全吗?我该如何解决这个问题?理想情况下,我会使用回调而不是 tx 来完成这项工作,这样我就可以从堆栈的视图中删除依赖性,但我也无法将闭包发送给 Send。
我正在使用这个库:https://github.com/jeaye/ncurses-rs
简化代码:
pub struct View {
max_x: i32,
max_y: i32,
messages_window: WINDOW,
input_window: Arc<Mutex<WINDOW>>
}
pub fn init(&mut self, input_tx: mpsc::Sender<DispatchMessage>) {
let input_window = self.input_window.clone();
thread::spawn(move || {
loop {
let input_window = input_window.lock().unwrap();
draw_prompt(input_window);
let input = prompt_input(input_window);
input_tx.send(input_to_message(input)).unwrap();
}
});
}
fn prompt_input(input: WINDOW) -> String {
let mut string = String::new();
wgetstr(input, &mut string);
string
}
fn draw_prompt(input: WINDOW) {
wclear(input);
let top = 0 as chtype;
let bottom = ' ' as chtype;
let empty = ' ' as chtype;
wborder(input, empty,empty,top,bottom,empty,empty,empty,empty);
mvwprintw(input, 1, 1, ">> ");
wrefresh(input);
}
我得到的错误:
src/view.rs:40:33: 40:45 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:40 draw_prompt(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:40:33: 40:45 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:41:46: 41:58 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:41 let input = prompt_input(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:41:46: 41:58 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:37:13: 37:26 error: the trait `core::marker::Send` is not implemented for the type `*mut ncurses::ll::WINDOW_impl` [E0277]
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
src/view.rs:37:13: 37:26 note: `*mut ncurses::ll::WINDOW_impl` cannot be sent between threads safely
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
error: aborting due to 3 previous errors
手动解除对 window 的引用可以消除类型错误,但我认为我会保留它,因为它可能表明出了什么问题。
Arc<T>
实现了 Send
,其中 T
实现了 Send
和 Sync
。 Mutex<T>
实现 Send
和 Sync
,其中 T
实现 Send
。所以 Arc<Mutex<T>>
仅在 T
实现 Send
时才实现 Send
。请记住,Send
表示“能够跨线程边界传输的类型”。 Arc<Mutex<T>>
允许从多个线程访问它的内容,纯粹处理所有权和可变性问题,所以如果底层类型不能跨线程边界传输,它也无济于事。您可能需要从一个线程执行所有 ncurses 操作。
Raw pointers 明确不实施 Send
因为无法保证它。您可以在其之上构造显式实现 Send
的类型,从而保证所包含的原始指针实际上对于跨线程边界传输是安全的。