This pertains to Ch 16.03 of The Book, specifically Arc
in multithreaded programs
I was just looking at the signature for thread::spawn
(documentation linked to by post URL) wondering if and how the requirement for a thread-safe smart pointer is enforced by the type system. In short, how is the use of Arc
necessitated by the type system??
For the signature, you get this:
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
Where the parameter f
is bound by F: FnOnce() -> T + Send + 'static
.
And ... I'm not entirely sure how I should think about this.
Obviously, Send
and 'static
here are related to my question, where in some way the closure must be thread-safe (through the Send
trait) and also have a whole-life-of-the-program lifetime (through the 'static
lifetime). Therefore, in some way, something like Rc
would be invalid but Arc
would be.
But how exactly?
- Are the bounds on the return type of the function/closure, which then sort of back propagate onto the input parameters or captured values of the function/closure?
- Or are these somehow properties of the function itself?
- And why is
T
separately bound by Send + 'static
when they are already present in the bounds on F
?
My best guess is that the bounds on F
are best parsed as ...
F: ( FnOnce() -> T ) + Send + 'static
T: Send + 'static
IE, Everything separated by a +
is unitary, and, therefore, FnOnce() -> T
is a single bound and Send
another separate bound.
But I'm unsure about that, haven't read that anywhere, and am not really sure how to understand how exactly a function can have Send
or 'static
without some logic linking that directly to its input parameters?
Thoughts?