2017-02-11 63 views
9

当我使用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(); 
} 

我测试了锈1.14和1.15,同样的问题出现在两个。

这是因为我使用了错误的东西还是它是一个错误?

回答

6

这是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。锈队目前是waiting for LLVM to provide a better solution

作为一种解决方法,您应该简单地在循环中执行一些操作,这可能是您想要执行的任何操作^ _^