Move semantics can be particularly useful when transferring resources between threads. When you want to pass an object from one thread to another, you typically want to avoid copying, as that could be expensive (especially for large objects) and could lead to race conditions if both threads try to access the same resource.
Instead, you can use move semantics to efficiently transfer ownership of the resource from one thread to the other. Once the resource is moved, the original thread no longer has access to it, preventing race conditions.
Here's an example using std::thread
and std::unique_ptr
:
#include <iostream>
#include <memory>
#include <thread>
using std::unique_ptr, std::thread;
class BigObject {
public:
BigObject() {
std::cout << "BigObject constructed\n";
}
~BigObject() {
std::cout << "BigObject destroyed\n";
}
void DoSomething() {
std::cout << "Doing something\n";
}
};
void ThreadFunction(unique_ptr<BigObject> obj) {
obj->DoSomething();
}
int main() {
unique_ptr<BigObject> obj{new BigObject{}};
thread t{ThreadFunction, std::move(obj)};
t.join();
}
BigObject constructed
Doing something
BigObject destroyed
In this example, we create a BigObject
managed by a unique_ptr
in the main thread. We then create a new thread, passing the unique_ptr
to the thread function using std::move()
. This transfers ownership of the BigObject
to the new thread.
Inside the thread function, we can use the BigObject
safely, knowing that no other thread has access to it. When the thread function ends, the unique_ptr
is destroyed, which in turn destroys the BigObject
.
This pattern ensures that:
BigObject
.BigObject
 at a time.BigObject
 is properly destroyed when it's no longer needed, regardless of how the thread ends.The same pattern can be used with other types that support move semantics, such as std::string
, std::vector
, and many other standard library types.
Of course, this is just one way to use move semantics with threads. Depending on your specific use case, you might use move semantics with other thread synchronization primitives like std::promise
and std::future
, or with thread-safe queue types for passing messages between threads.
Answers to questions are automatically generated and may not have been reviewed.
Learn how we can improve the performance of our types using move constructors, move assignment operators and std::move()