当我使用 rustc 1.rs
编译以下代码时,它按预期无休止地运行。
use std::thread;
fn main() {
thread::spawn(|| {
let a = 2;
loop {
a*a;
}
}).join();
}
一个较短的版本:
use std::thread;
fn main() {
thread::spawn(|| {
loop {}
}).join();
}
但是,如果我使用 rustc -O 1.rs
编译上面的两个程序,它们会崩溃:
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 0, message: "Success" } }', src/libcore/result.rs:837
stack backtrace:
1: 0x5650bd0acada - std::sys::imp::backtrace::tracing::imp::write::h917062bce4ff48c3
at /build/rustc-1.14.0+dfsg1/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
2: 0x5650bd0b068f - std::panicking::default_hook::{{closure}}::h0bacac31b5ed1870
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:247
3: 0x5650bd0aee7c - std::panicking::default_hook::h5897799da33ece67
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:263
4: 0x5650bd0af4d7 - std::panicking::rust_panic_with_hook::h109e116a3a861224
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:451
5: 0x5650bd0af364 - std::panicking::begin_panic::hbb38be1379e09df0
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:413
6: 0x5650bd0af289 - std::panicking::begin_panic_fmt::h26713cea9bce3ab0
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:397
7: 0x5650bd0af217 - rust_begin_unwind
at /build/rustc-1.14.0+dfsg1/src/libstd/panicking.rs:373
8: 0x5650bd0e2f3d - core::panicking::panic_fmt::hcfbb59eeb7f27f75
at /build/rustc-1.14.0+dfsg1/src/libcore/panicking.rs:69
9: 0x5650bd0a6e84 - core::result::unwrap_failed::h15a0fc826f4081f4
10: 0x5650bd0b7ffa - __rust_maybe_catch_panic
at /build/rustc-1.14.0+dfsg1/src/libpanic_unwind/lib.rs:97
11: 0x5650bd0a6fc1 - <F as alloc::boxed::FnBox<A>>::call_box::he32a93ebea7bc7ad
12: 0x5650bd0ae6c4 - std::sys::imp::thread::Thread::new::thread_start::ha102a6120fc52763
at /build/rustc-1.14.0+dfsg1/src/liballoc/boxed.rs:605
at /build/rustc-1.14.0+dfsg1/src/libstd/sys_common/thread.rs:21
at /build/rustc-1.14.0+dfsg1/src/libstd/sys/unix/thread.rs:84
13: 0x7fc2d0042423 - start_thread
14: 0x7fc2cfb6e9be - __clone
15: 0x0 - <unknown>
如果我删除闭包中的所有代码,它会无错退出:
use std::thread;
fn main() {
thread::spawn(|| {
}).join();
}
如果我在循环中添加 println!()
,它也能正常工作:
use std::thread;
fn main() {
thread::spawn(|| {
loop {
println!("123")
}
}).join();
}
我在 Rust 1.14 和 1.15 上测试了这个,两者都出现了同样的问题。
这是因为我用错了什么还是有错误?
最佳答案
这是一个 known issue (#28728) .简而言之,LLVM 优化了 have no observable side-effects 的循环:
The implementation may assume that any thread will eventually do one of the following:
- terminate
- make a call to a library I/O function
- access or modify a volatile object, or
- perform a synchronization operation or an atomic operation
在这种情况下,这些都不成立,因此 LLVM 完全删除了循环。然而,Rust 编译器生成的代码假定循环永远不会返回。这种不匹配会导致崩溃。
因为没有副作用的无限循环基本上是没有用的,这个问题是not of critical priority . Rust 团队目前是 waiting for LLVM to provide a better solution .
作为解决方法,您应该在循环内简单地做一些事情,这可能是您无论如何都想做的事情 ^_^
关于multithreading - 启用优化后,带有衍生线程的程序会出现困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42182573/