我需要在Rust中暂停当前线程并从另一个线程进行通知。在Java中,我会这样写:
synchronized(myThread) {
myThread.wait();
}
并从第二个线程(以恢复主线程):
synchronized(myThread){
myThread.notify();
}
能否在Rust中实现相同的功能?
我需要在Rust中暂停当前线程并从另一个线程进行通知。在Java中,我会这样写:
synchronized(myThread) {
myThread.wait();
}
并从第二个线程(以恢复主线程):
synchronized(myThread){
myThread.notify();
}
()
的通道可能是最简单的:use std::sync::mpsc::channel;
use std::thread;
let (tx,rx) = channel();
// Spawn your worker thread, giving it `send` and whatever else it needs
thread::spawn(move|| {
// Do whatever
tx.send(()).expect("Could not send signal on channel.");
// Continue
});
// Do whatever
rx.recv().expect("Could not receive from channel.");
// Continue working
< p > ()
类型是因为它实际上没有任何信息,这意味着很明显你只是用它作为一个信号。它大小为零的事实也意味着在某些情况下它可能更快(但实际上可能不比正常的机器字写入更快)。< /p>
< p >如果您只需要通知程序线程已经完成,您可以获取其 join guard 并等待其加入。< /p>
let guard = thread::spawn( ... ); // This will automatically join when finished computing
guard.join().expect("Could not join thread");
在你想要等待的线程中,
fn worker_thread() {
std::thread::park();
}
fn main_thread(worker_thread: std::thread::Thread) {
worker_thread.unpark();
}
unpark
的情况下唤醒。您应该在代码中为这种情况做好准备,或者像建议的那样使用std::sync::mpsc::channel之类的工具。std::sync::mpsc
有两个通道(异步和同步),取决于您的需求。在这里,异步通道更加匹配:std::sync::mpsc::channel
。有一个监控的板条箱,通过将Mutex
和Condvar
结合在一个方便的结构中提供此功能。
(完全披露:我是作者。)
简而言之,可以像这样使用:
let mon = Arc::new(Monitor::new(false));
{
let mon = mon.clone();
let _ = thread::spawn(move || {
thread::sleep(Duration::from_millis(1000));
mon.with_lock(|mut done| { // done is a monitor::MonitorGuard<bool>
*done = true;
done.notify_one();
});
});
}
mon.with_lock(|mut done| {
while !*done {
done.wait();
}
println!("finished waiting");
});
mon.with_lock(...)
在语义上等同于 Java 的 synchronized(mon) {...}
。
wait()/notify()
而没有while
循环是一个不好的想法 -wait()
可能会停止等待,而没有调用notify()
,这被称为虚假唤醒。使用专门的原语,如CountDownLatch
或Exchanger<Void>
将会更好;在下面的答案中,它与Rust中的通道非常相似。 - Vladimir Matveev