#thread #terminate #pthreads #sync #standard #macos #terminatable

terminate-thread

使用pthread实现的简单可终止线程

2个不稳定版本

0.3.1 2024年1月20日
0.3.0 2024年1月20日
0.2.0 2024年1月20日
0.1.1 2024年1月20日
0.1.0 2024年1月20日

#3 in #terminate

每月35次下载

MIT许可证

35KB
531

包含 (神秘的autoconf代码,1KB) cbits/configure.ac

这是什么?

它只是用pthread为Rust实现的简单可终止线程

但是为什么?

有时,我需要终止一个阻塞的线程。没有方法可以

在不将其放入某个Sync东西的情况下使用标准std::thread来完成。

如何使用它?

[dependencies]
terminate-thread = "0.3"

启动您的线程

use terminate_thread::Thread;
Thread::spawn(|| {}).join(); // ← spawn & join (>= 0.3.0) your thread

手动终止您的线程

use terminate_thread::Thread;
let thr = Thread::spawn(|| loop {
    // infinite loop in this thread
    println!("loop run");
    std::thread::sleep(std::time::Duration::from_secs(1));
});
std::thread::sleep(std::time::Duration::from_secs(1));
thr.terminate() // ← the thread is terminated manually!

自动终止您的线程

use terminate_thread::Thread;
{
    let _thread = Thread::spawn(|| loop {}); // ← the thread will be terminated when thread is dropped
}

对panic有容忍性(v0.3.1,仅限macOS)

use terminate_thread::Thread;
Thread::spawn(|| panic!()); // ← this is fine
let thread = Thread::spawn(|| panic!("your message")).join(); // ← thread stores the panic info
assert!(thread.over() && thread.panics()); // ← it's over and panics
let info = thread.panic_info().lock().unwrap().take().unwrap(); // ← take out the panic info
assert_eq!(info.downcast_ref::<&str>().unwrap(), &"your message"); // ← get your panic info

不是一个好主意!

终止正在运行的线程是绝对不是一个好主意

更好的方法是使用类似std::sync::atomic::AtomicBool的东西,

给您的线程一个返回的机会。

测试平台

  • Linux
  • macOS

它应该在支持pthread的任何平台上工作,

但现实世界很复杂,不能做出任何承诺。

待办事项

  • 终止panic的任务。>= v0.3.0
use terminate_thread::Thread;
Thread::spawn(|| panic!()); // ← this is fine

let thread = Thread::spawn(|| panic!()).join(); // ← thread stores the panic info
assert!(thread.over() && thread.panics()); // ← it's over and panics

问题

  • 太快的终止线程会导致panic。>= v0.2.0
use terminate_thread::Thread;
Thread::spawn(|| {}); // ← bus error
  • std::panic::AssertUnwindSafe()在Linux中不起作用。== v0.3.0
use terminate_thread::Thread;
Thread::spawn(|| panic!()); // ← FATAL: exception not rethrown

无运行时依赖

~0–2MB
~40K SLoC