Как два или более потока обмениваются памятью в куче, которую они выделили?

Как гласит название, как два или более потока обмениваются памятью в куче, которую они выделили? Я думал об этом, и я не могу понять, как они могут это сделать. Вот мое понимание процесса, по-видимому, я где-то ошибаюсь.

Любой поток может добавить или удалить определенное количество байтов в куче, сделав системный вызов, который возвращает указатель на эти данные, предположительно, путем записи в регистр, который поток может затем скопировать в стек. Таким образом, два потока A и B могут выделять столько памяти, сколько они хотят. Но я не вижу, как поток A может знать, где находится память, выделенная потоком B. Я также не знаю, как нить может знать, где находится другой стек потока. Многопоточные программы разделяют кучу и, я считаю, могут обращаться друг к другу, но я не могу понять, как это сделать.

Я попытался найти этот вопрос, но нашел только конкретные версии, которые абстрагируют детали.

Изменение: я стараюсь не быть языком или ОС, но я использую Linux, и я смотрю на него с низкой точки зрения, сборка, я думаю.

Ответ 1

Моя интерпретация вашего вопроса: как можно использовать поток A для указания указателя на память B? Как они могут обмениваться данными?

Ответ: Обычно они начинаются с общего указателя на общую область памяти. Это позволяет им обмениваться другими данными, включая указатели на другие данные друг с другом.

Пример:

  1. Основной поток выделяет некоторую общую память и сохраняет ее местоположение в p
  2. Основной поток запускает два рабочих потока, передавая им указатель p
  3. Рабочие теперь могут использовать p и работать с данными, на которые указывает p

И на реальном языке (С#) это выглядит так:

//start function ThreadProc and pass someData to it
new Thread(ThreadProc).Start(someData)

Нитки обычно не имеют доступа друг к другу. Все начинается с одного указателя, переданного в процедуру потока.


Создание потока - это функция ОС. Он работает следующим образом:

  1. Приложение вызывает ОС с использованием стандартного ABI/API
  2. ОС выделяет стекную память и внутренние структуры данных
  3. ОС "подделывает" первый стек кадров: он устанавливает указатель на ThreadProc и "толкает" некоторые данные в стек. Я говорю "кузница", потому что этот первый стек кадров не возникает естественным образом, но создается искусственно.
  4. ОС планирует поток. ThreadProc не знает, что он был настроен на новый стек. Все, что он знает, это то, что someData находится в обычной позиции стека, где он ожидал бы этого.

И вот как некоторые данные поступают в ThreadProc. Таким образом, первый, начальный элемент данных является общим. Шаги 1-3 выполняются синхронно родительским потоком. 4 происходит на дочернем потоке.

Ответ 2

Очень короткий ответ с высоты птичьего полета (1000 миль выше):
Нитки - это пути выполнения одного и того же процесса, и куча фактически принадлежит процессу (и в результате разделяется потоками). Каждому потоку просто нужен собственный стек, чтобы функционировать как отдельная единица работы.

Ответ 3

Темы могут делиться памятью в куче, если они используют одну и ту же кучу. По умолчанию большинство языков/фреймворков имеют единую кучу по умолчанию, которую код может использовать для выделения памяти из кучи. В неуправляемых языках вы обычно делаете явные вызовы для выделения памяти кучи. В C это может быть malloc и т.д., Например. В управляемых языках распределение кучи обычно автоматическое, и то, как выполняется выделение, зависит от языка - обычно с помощью new оператора. но это немного зависит от контекста. Если вы задаете условия ОС или языка, о которых вы спрашиваете, я мог бы предоставить более подробную информацию.

Ответ 4

Тема, совместно используемая другими потоками, относящимися к одному и тому же процессу: его секция кода, раздел данных и другие ресурсы операционной системы, такие как открытые файлы и сигналы.