Как два или более потока обмениваются памятью в куче, которую они выделили?
Как гласит название, как два или более потока обмениваются памятью в куче, которую они выделили? Я думал об этом, и я не могу понять, как они могут это сделать. Вот мое понимание процесса, по-видимому, я где-то ошибаюсь.
Любой поток может добавить или удалить определенное количество байтов в куче, сделав системный вызов, который возвращает указатель на эти данные, предположительно, путем записи в регистр, который поток может затем скопировать в стек. Таким образом, два потока A и B могут выделять столько памяти, сколько они хотят. Но я не вижу, как поток A может знать, где находится память, выделенная потоком B. Я также не знаю, как нить может знать, где находится другой стек потока. Многопоточные программы разделяют кучу и, я считаю, могут обращаться друг к другу, но я не могу понять, как это сделать.
Я попытался найти этот вопрос, но нашел только конкретные версии, которые абстрагируют детали.
Изменение: я стараюсь не быть языком или ОС, но я использую Linux, и я смотрю на него с низкой точки зрения, сборка, я думаю.
Ответы
Ответ 1
Моя интерпретация вашего вопроса: как можно использовать поток A для указания указателя на память B? Как они могут обмениваться данными?
Ответ: Обычно они начинаются с общего указателя на общую область памяти. Это позволяет им обмениваться другими данными, включая указатели на другие данные друг с другом.
Пример:
- Основной поток выделяет некоторую общую память и сохраняет ее местоположение в
p
- Основной поток запускает два рабочих потока, передавая им указатель
p
- Рабочие теперь могут использовать
p
и работать с данными, на которые указывает p
И на реальном языке (С#) это выглядит так:
//start function ThreadProc and pass someData to it
new Thread(ThreadProc).Start(someData)
Нитки обычно не имеют доступа друг к другу. Все начинается с одного указателя, переданного в процедуру потока.
Создание потока - это функция ОС. Он работает следующим образом:
- Приложение вызывает ОС с использованием стандартного ABI/API
- ОС выделяет стекную память и внутренние структуры данных
- ОС "подделывает" первый стек кадров: он устанавливает указатель на ThreadProc и "толкает" некоторые данные в стек. Я говорю "кузница", потому что этот первый стек кадров не возникает естественным образом, но создается искусственно.
- ОС планирует поток. ThreadProc не знает, что он был настроен на новый стек. Все, что он знает, это то, что someData находится в обычной позиции стека, где он ожидал бы этого.
И вот как некоторые данные поступают в ThreadProc. Таким образом, первый, начальный элемент данных является общим. Шаги 1-3 выполняются синхронно родительским потоком. 4 происходит на дочернем потоке.
Ответ 2
Очень короткий ответ с высоты птичьего полета (1000 миль выше):
Нитки - это пути выполнения одного и того же процесса, и куча фактически принадлежит процессу (и в результате разделяется потоками). Каждому потоку просто нужен собственный стек, чтобы функционировать как отдельная единица работы.
Ответ 3
Темы могут делиться памятью в куче, если они используют одну и ту же кучу. По умолчанию большинство языков/фреймворков имеют единую кучу по умолчанию, которую код может использовать для выделения памяти из кучи. В неуправляемых языках вы обычно делаете явные вызовы для выделения памяти кучи. В C это может быть malloc
и т.д., Например. В управляемых языках распределение кучи обычно автоматическое, и то, как выполняется выделение, зависит от языка - обычно с помощью new
оператора. но это немного зависит от контекста. Если вы задаете условия ОС или языка, о которых вы спрашиваете, я мог бы предоставить более подробную информацию.
Ответ 4
Тема, совместно используемая другими потоками, относящимися к одному и тому же процессу: его секция кода, раздел данных и другие ресурсы операционной системы, такие как открытые файлы и сигналы.