Uh oh!
There was an error while loading. Please reload this page.
Conversation
ghost
commented
Mar 8, 2018
An interesting comment I found in // Note that we **do not** run these tests here. The windows builders get super// unhappy if a thread outlives the main thread and then exits at the same time// (something deadlocks) so we just avoid this entirely by not running these// tests./// ```no_run/// use std::sync::Arc;/// use std::thread;////// let five = Arc::new(5);////// for _ in 0..10 {/// let five = Arc::clone(&five);////// thread::spawn(move || {/// println!("{:?}", five);/// });/// }/// ``` |
| /// [`Clone`]: ../../std/clone/trait.Clone.html | ||
| /// [`thread::spawn`]: fn.spawn.html | ||
| /// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn | ||
| #[must_use] |
There was a problem hiding this comment.
It might be a good idea to add a short message, describing the reason for must_use, like
#[must_use = "it is better to explicitly join the spawned thread, otherwise it might be terminated abruptly, without running destructors"]
| //! When the main thread of a Rust program terminates, the entire program shuts | ||
| //! down, even if other threads are still running. However, this module provides | ||
| //! convenient facilities for automatically waiting for the termination of a | ||
| //! child thread (i.e., join). |
There was a problem hiding this comment.
Written in 2014. I wish it were still true.
emilyalbini
commented
Mar 8, 2018
Highfive failed to assign a reviewer, @Kimundi? |
matklad
commented
Mar 8, 2018
I think we might want to cc @rust-lang/libs here: there will be a lot of warnings because of this, so it's better to discuss this at the team level just in case I think? |
Kimundi
commented
Mar 8, 2018
Yeah, this seems like it might have a lot of impact. |
alexcrichton
commented
Mar 8, 2018
Thanks for the PR @stjepang! I'd personally think, however, that we would not want to do this. I think it's a laudable effort to encourage authors to think about shutdown and how to join threads, but there's a few reasons that I think we won't want to take this strategy:
I wonder though if there's perhaps another route we can take for warning about this? Not much comes to mind though :( |
I'd say the key issue here is that Maybe we don't need to "fix" let guard = thread::guarded(move || {// ...});// Join the thread.// Panics if the thread ended with a panic.drop(guard);Also, I find the fact that the documentation says the following amusing: //! When the main thread of a Rust program terminates, the entire program shuts//! down, even if other threads are still running. However, this module provides//! convenient facilities for automatically waiting for the termination of a//! child thread (i.e., join).We're being warned than daemonized threads will not be cleanly shut down, but fret not - we're covered by convenient facilities for automatic joining. Except that's a lie - there is nothing automatic about calling |
alexcrichton
commented
Mar 9, 2018
Having an alternative seems plausible to me! |
bors
commented
Mar 11, 2018
☔ The latest upstream changes (presumably #48691) made this pull request unmergeable. Please resolve the merge conflicts. |
shepmaster
commented
Mar 18, 2018
Where does this PR stand? Should it be closed in favor of a new API addition like the proposed |
shepmaster
commented
Mar 23, 2018
Well, now you gotta talk about it at your meeting, so there 😝 |
emilyalbini
commented
Apr 16, 2018
Ping from triage @rust-lang/libs! What's the decision on this? |
alexcrichton
commented
Apr 16, 2018
We'll have triage this wednesday and I'll make sure we discuss it there |
sfackler
commented
Apr 19, 2018
We discussed this in triage and like the approach of a separate function which has a |
SimonSapin
commented
Apr 19, 2018
Isn’t |
sfackler
commented
Apr 19, 2018
Mostly but not entirely! In this case, code like thread::spawn_attached(|| do_expensive_work());Is totally broken - we're presumably doing this work in a separate thread because we want to do other stuff while it's running, but the handle is going to join when it's dropped immediately. |
emilyalbini
commented
Apr 30, 2018
If I understood this correctly the PR needs to change? Marking as waiting on author @stjepang. |
ghost
commented
Apr 30, 2018
Let's close this PR since it's definitely not the direction we're going to take. The alternative is to add a new function for spawning threads that returns a join-on-drop guard. |
|
This PR adds a
#[must_use]attribute toJoinHandle.The change may introduce a considerable number of warnings in the Rust code, but that's a good thing! Note that warnings are still easy to get around by writing
let _ = std::thread::spawn(...), but at least they make the user think twice about forgetting to join the thread.Generally speaking, spawning a thread with no intention of ever joining should be discouraged since it may lead to very subtle bugs. See #48820 for an explanation.
Closes#48820
cc @matklad