Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory sharing between C++ threads

Tags:

I'm new to threading in C++, and I'm trying to get a clear picture about how memory is shared/not shared between threads. I'm using std::thread with C++11. From what I've read on other SO questions, stack memory is owned by only one thread and heap memory is shared between threads. So from what I think I understand about the stack vs. the heap, the following should be true:

#include <thread> using namespace std;  class Obj { public:     int x;     Obj(){x = 0;} };  int main() {     Obj stackObj;     Obj *heapObj = new Obj();     thread t([&]{         stackObj.x++;         heapObj->x++;     });     t.join();     assert(heapObj->x == 1);     assert(stackObj.x == 0); } 

forgive me if I screwed up a bunch of stuff, lambda syntax is very new to me. But hopefully what I'm trying to do is coherent. Would this perform as I expect? And if not, what am I misunderstanding?

like image 605
Michael Dorst Avatar asked Jul 05 '12 20:07

Michael Dorst


People also ask

Do threads share memory C?

It depends on how you pass the variable, and where it is declared. Each thread has its own stack, and thus their own local variables (unless they are static) Everything in C is pass-by-value, so a copy would be made, but you might do something else, e.g. pass a pointer to i .

Can two threads share memory?

Any thread can add or remove a given number of bytes on the heap by making a system call which returns a pointer to this data, presumably by writing to a register which the thread can then copy to the stack. So two threads A and B can allocate as much memory as they want.

How can I share data between two threads?

All static and controlled data is shared between threads. All other data can also be shared through arguments/parameters and through based references, as long as the data is allocated and is not freed until all of the threads have finished using the data.

Can multiple threads read the same memory?

Not only are different cores allowed to read from the same block of memory, they're allowed to write at the same time too.


1 Answers

Memory is memory. An object in C++ occupies some location in memory; that location may be on a stack or on the heap, or it may have been statically allocated. It doesn't matter where the object is located: any thread that has a reference or pointer to the object may access the object. If two threads have a reference or a pointer to the object, then both threads may access it.

In your program, you create a worker thread (by constructing a std::thread) that executes the lambda expression you provide it. Because you capture both stackObj and heapObj by reference (using the [&] capture default), that lambda has references to both of those objects.

Those objects are both located on the main thread's stack (note that heapObj is a pointer-type object that is located on the main thread's stack and points to a dynamically allocated object that is located on the heap). No copies of these objects are made; rather, your lambda expression has references to the objects. It modifies the stackObj directly and modifies the object pointed to by heapObj indirectly.

After the main thread joins with the worker thread, both heapObj->x and stackObj.x have a value of 1.


If you had used the value capture default ([=]), your lambda expression would have copied both stackObj and heapObj. The expression stackObj.x++ in the lambda expression would increment the copy, and the stackObj that you declare in main() would be left unchanged.

If you capture the heapObj by value, only the pointer itself is copied, so while a copy of the pointer is used, it still points to the same dynamically allocated object. The expression heapObj->x++ would dereference that pointer, yielding the Obj you created via new Obj(), and increment its value. You would then observe at the end of main() that heapObj->x has been incremented.

(Note that in order to modify an object captured by value, the lambda expression must be declared mutable.)

like image 83
James McNellis Avatar answered Sep 19 '22 13:09

James McNellis