Rust中使用thread:sleep和print导致的执行顺序问题
Rust中使用thread:sleep和print!宏引起的执行顺序问题探究
以下是C#代码:
static void Main(string[] args)
{
System.Console.Write("Hello ");
System.Threading.Thread.Sleep(System.TimeSpan.FromSeconds(3));
System.Console.Write("World");
}
在Visual Studio界面按F5编译并执行,在打印出Hello
字符串后,等待3秒(大约),打印出World
字符串。
同样的逻辑,以下是Rust代码:
fn main() {
print!("Hello ");
std::thread::sleep(std::time::Duration::from_secs(3));
print!("World");
}
使用cargo run
编译并运行,奇怪的一幕出现了,等待了大概3秒之后,屏幕一起打印出了Hello World
字符串!
难道,Rust中的thead::sleep()
方法打乱了print!的执行顺序?
带着疑问,我查看了print!
宏的实现方法:
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(print_internals)]
macro_rules! print {
($($arg:tt)*) => ($crate::io::_print($crate::format_args!($($arg)*)));
}
看太懂(😂😂😂)。。。往上看:
/// Prints to the standard output.
///
/// Equivalent to the [`println!`] macro except that a newline is not printed at
/// the end of the message.
///
/// Note that stdout is frequently line-buffered by default so it may be
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
/// immediately.
///
/// Use `print!` only for the primary output of your program. Use
/// [`eprint!`] instead to print error and progress messages.
///
/// [flush]: crate::io::Write::flush
///
/// # Panics
///
/// Panics if writing to `io::stdout()` fails.
///
/// # Examples
///
/// ```
/// use std::io::{self, Write};
///
/// print!("this ");
/// print!("will ");
/// print!("be ");
/// print!("on ");
/// print!("the ");
/// print!("same ");
/// print!("line ");
///
/// io::stdout().flush().unwrap();
///
/// print!("this string has a newline, why not choose println! instead?\n");
///
/// io::stdout().flush().unwrap();
/// ```
哈哈,原来是因为使用print!
宏时,stdout
有默认的行缓冲,所以导致不能立即把缓冲区内容刷新到屏幕上。如果需要立即显示,需要使用 io::stdout().flush()
方法立即刷新。
于是在thread::sleep
之前添加flush()
方法:
fn main() {
print!("Hello ");
std::io::stdout().flush().unwarp();
std::thread::sleep(std::time::Duration::from_secs(3));
print!("World");
}
一切正常。
C#中对使用write
打印内容时立刷新到了屏幕,而Rust中的print!
宏却没有。但是Rust的println!
宏实现了立即刷新功能,其中考量,不得而知。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!