How do two or more threads share memory on the heap that they have allocated?

Viewed 29612

As the title says, how do two or more threads share memory on the heap that they have allocated? I've been thinking about it and I can't figure out how they can do it. Here is my understanding of the process, presumably I am wrong somewhere.

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. But I don't see how thread A could know where the memory that thread B has allocated is located. Nor do I know how either thread could know where the other thread's stack is located. Multi-threaded programs share the heap and, I believe, can access one another's stack but I can't figure out how.

I tried searching for this question but only found language specific versions that abstract away the details.

Edit: I am trying not to be language or OS specific but I am using Linux and am looking at it from a low level perspective, assembly I guess.

5 Answers

The part you are missing is static memory containing static variables.

This memory is allocated when the program is started, and assigned known adresses (determined at the linking time). All threads can access this memory without exchanging any data runtime, because the addresses are effectively hardcoded.

A simple example might look like this:

// Global variable.
std::atomic<int> common_var;

void thread1() {
  common_var = compute_some_value();
}

void thread2() {
  do_something();
  int current_value = common_var;
  do_more();
}

And of course the global value may be a pointer, that can be used to exchange heap memory. The producer allocates some objects, the consumer takes and uses them.

// Global variable.
std::atomic<bool> produced;
SomeData* data_pointer;

void producer_thread() {
  while (true) {
    if (!produced) {
      SomeData* new_data = new SomeData();
      data_pointer = new_data;
      // Let the other thread know there is something to read.
      produced = true;
    }
  }
}

void consumer_thread() {
  while (true) {
    if (produced) {
      SomeData* my_data = data_pointer;
      data_pointer = nullptr;
      // Let the other thread know we took the data.
      produced = false;
      do_something_with(my_data);
      delete my_data;
    }
  }
}

Please note: these are not examples of good concurrent code, but they show the general idea without too much clutter.

Related