Reputation: 168
Struct S
may be actually some big data, for example a large Vec
. If I have one thread and do not use the data after creating a thread, I can move data to it, but with two threads (or using the same data in main thread), it is impossible.
struct S {
i : i32,
}
fn thr(s : &S)
{
}
fn main()
{
let s1 = S { i:1 };
thr(&s1);
let t1 = std::thread::spawn(|| thr(&s1)); // does not work
let t2 = std::thread::spawn(|| thr(&s1)); // does not work
t1.join();
t2.join();
}
Upvotes: 1
Views: 703
Reputation: 847
If this is C or C++ the allocated memory won't go away until its explicitly freed, and also, unless the objects are declared threadlocal then all threads in your app can refer to them.
In the code you wrote it seems your structure is on the stack rather than the heap, so once it goes out of scope that object pointer is invalid.
The brutal way to deal with this, without ARC, is to simply allocate the object and the pass the allocated pointer to your threads. Some thread needs to be the one to ultimately delete it (that's where ARC is a good idea).
Upvotes: 0
Reputation: 430514
I'd highly recommend reading The Rust Programming Language, specifically the chapter on concurrency. In it, you are introduced to Arc
:
use std::sync::Arc;
struct S {
i: i32,
}
fn thr(s: &S) {}
fn main() {
let s1 = Arc::new(S { i: 1 });
thr(&s1);
let s2 = s1.clone();
let t2 = std::thread::spawn(move || thr(&s2));
let s3 = s1.clone();
let t3 = std::thread::spawn(move || thr(&s3));
t2.join();
t3.join();
}
Notably, when Arc
s are cloned, they simply bump a reference count, not duplicate the contained data.
Upvotes: 7