当我在Rust中spawn
一个线程时,我得到一个JoinHandle
,这对于...加入(阻塞操作)很有用,而不是其他。如何从父线程检查子线程是否已退出(即JoinHandle.join()
不会阻塞)?如果您知道如何杀死子线程,则可获得奖励。
我想你可以通过创建一个频道,向孩子发送内容,捕捉错误来做到这一点,但这似乎是不必要的复杂性和开销。
答案 0 :(得分:9)
从Rust 1.7开始,标准库中没有API来检查子线程是否已经退出而没有阻塞。
便携式解决方法是使用channels从孩子向父母发送消息,以表示孩子即将退出。 Receiver
有一种非阻塞try_recv
方法。当try_recv
收到邮件时,您可以使用join()
上的JoinHandle
来检索帖子的结果。
还有一些不稳定的特定于平台的扩展特性,可以让您获取原始线程句柄。然后,您必须编写特定于平台的代码来测试该线程是否已退出。
如果您认为此功能应该在Rust的标准库中,您可以submit an RFC(请务必先阅读README!)。
如果您知道如何杀死子线程,则获得积分。
Rust中的线程是使用本机OS线程实现的。即使操作系统可能提供了一种杀死线程的方法,这样做是个坏主意,因为在进程之前,线程分配的资源不会被清除>结束。
答案 1 :(得分:9)
简短的回答是不可能的。但这不是应该真正解决的问题。
如果您知道如何杀死子线程,则获得积分。
<强> NEVER 强>
即使在支持杀死线程(see Java here)的语言中,也不建议使用。
线程的执行通常用显式交互点编码,并且通常存在隐式假设,不会发生其他中断。
最令人震惊的例子当然是资源:天真的&#34;杀人&#34;方法是停止执行线程;这意味着不会释放任何资源。你可能会考虑记忆,这是你最不担心的事情。相反,想象一下,所有未解锁的Mutex
会在以后创建死锁......
另一种选择是在线程中注入panic
,这将导致展开。但是,你不能只是在任何时候开始放松!该程序必须定义安全点,注入panic
将保证安全(在任何其他点注入它意味着可能破坏共享对象);如何定义这样的安全点并注入panic
在本地语言中存在一个开放的研究问题,特别是那些在系统W^X
上执行的问题(其中内存页面是可写的或可执行的但从不两者都有)。
总之,没有已知的安全方法(内存方式和功能方面)杀死线程。
答案 2 :(得分:4)
有可能,朋友们。使用 refcounters ,Rust会在结束或恐慌时放弃。 100%安全。例如:
use std::time::Duration;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
fn main() {
// Play with this flag
let fatal_flag = true;
let do_stop = true;
let working = Arc::new(AtomicBool::new(true));
let control = Arc::downgrade(&working);
thread::spawn(move || {
while (*working).load(Ordering::Relaxed) {
if fatal_flag {
panic!("Oh, my God!");
} else {
thread::sleep(Duration::from_millis(20));
println!("I'm alive!");
}
}
});
thread::sleep(Duration::from_millis(50));
// To stop thread
if do_stop {
match control.upgrade() {
Some(working) => (*working).store(false, Ordering::Relaxed),
None => println!("Sorry, but thread died already."),
}
}
thread::sleep(Duration::from_millis(50));
// To check it's alive / died
match control.upgrade() {
Some(_) => println!("Thread alive!"),
None => println!("Thread ends!"),
}
}
要点:https://gist.github.com/DenisKolodin/edea80f2f5becb86f718c330219178e2
在游乐场:https://play.rust-lang.org/?gist=9a0cf161ba0bbffe3824b9db4308e1fb&version=stable&backtrace=0
UPD :我创建了thread-control
crate来实现这种方法:https://github.com/DenisKolodin/thread-control
答案 3 :(得分:0)
我认为可以用Arc解决这个问题 如果线程退出,则参考计数器减一。