Why do I get different behavior for `print!` and `println!` when using threads?

I have the following pieces of code:

use std::thread;
use std::sync::mpsc;
use std::time::Duration;

fn main() {
	let (tx, rx) = mpsc::channel();
	thread::spawn(move || {
		let vals = vec![
			String::from("The"),
			String::from("Quick"),
			String::from("Brown"),
			String::from("Fox"),
			String::from("Jumped"),
			String::from("Over"),
			String::from("The"),
			String::from("Lazy"),
			String::from("Dog."),
		];

		for val in vals {
			tx.send(val).unwrap();
			thread::sleep(Duration::from_secs(1));
		}
	});

	for received in rx {
		print!("{} ", received);
	}
	println!("");
}

and

use std::thread;
use std::sync::mpsc;
use std::time::Duration;

fn main() {
	let (tx, rx) = mpsc::channel();
	thread::spawn(move || {
		let vals = vec![
			String::from("The"),
			String::from("Quick"),
			String::from("Brown"),
			String::from("Fox"),
			String::from("Jumped"),
			String::from("Over"),
			String::from("The"),
			String::from("Lazy"),
			String::from("Dog."),
		];

		for val in vals {
			tx.send(val).unwrap();
			thread::sleep(Duration::from_secs(1));
		}
	});

	for received in rx {
		println!("{} ", received);
	}
	println!("");
}

If I run the first code, about 10 seconds elapse before I see any output but the second behaves as expected with a line being output to stdout every second. I would appreciate an explanation to why the above happens as outlined.

1 Like

Stdout is line buffered. It will only perform the actual system write when it gets a newline, unless you manually flush it.

2 Likes

Which can be done with the following:

print!("");
std::io::stdout().flush();
1 Like

Nice! Thanks.

I had to add the following lines to my code:

use std::io::*;
...
        for received in rx {
		print!("{} ", received);
		std::io::stdout().flush().unwrap();
	}
...