Насколько я знаю, каждый поток получает отдельный стек, когда поток создается операционной системой. Интересно, имеет ли каждый поток кучу, отличную для себя?
У потоков есть отличная куча?
Ответ 1
Нет. Все потоки имеют общую кучу.
Каждый поток имеет отдельный стек, который он может быстро добавлять и удалять. Это делает стек основанную память быстрой, но если вы используете слишком много памяти стека, как это происходит в бесконечной рекурсии, вы получите переполнение стека.
Поскольку все потоки имеют одну и ту же кучу, необходимо синхронизировать доступ к распределителю/деаллокатору. Существуют различные методы и библиотеки, позволяющие избежать конкуренции .
Некоторые языки позволяют создавать частные пулы памяти или отдельные кучи, которые вы можете назначить одному потоку.
Ответ 2
По умолчанию C имеет только одну кучу.
Тем не менее, некоторые распределители, которые знают о потоках, будут разделять кучу, чтобы каждый поток имел свою собственную область для выделения. Идея состоит в том, что это должно сделать шкалу кучи лучше.
Одним из примеров такой кучи является Hoard.
Ответ 3
Зависит от ОС. Стандартная среда выполнения c Windows и унификации использует общую кучу по потокам. Это означает блокировку каждого malloc/free.
На Symbian, например, каждый поток имеет свою собственную кучу, хотя потоки могут совместно использовать указатели на данные, выделенные в любой куче. По-моему, дизайн Symbian лучше, поскольку он не только устраняет необходимость блокировки во время alloc/free, но также способствует чистой спецификации владения данными между потоками. Также в том случае, когда поток умирает, он принимает все объекты, которые он выделяет вместе с ним, то есть он не может течь объекты, которые он выделил, что является важным свойством для мобильных устройств с ограниченной памятью.
Эрланг также следует аналогичной конструкции, где "процесс" действует как единица сбора мусора. Все данные передаются между процессами путем копирования, за исключением двоичных blobs, которые подсчитываются по ссылке (я думаю).
Ответ 4
Каждый поток имеет свой стек и стек вызовов.
Каждый поток имеет одну и ту же кучу.
Ответ 5
Это зависит от того, что именно вы имеете в виду, говоря "куча".
Все потоки разделяют адресное пространство, поэтому объекты, выделенные кучей, доступны из всех потоков. Технически, стеки совместно используются в этом смысле, т.е. Ничто не мешает вам получать доступ к другому потоку потоков (хотя это почти никогда не имеет смысла делать это).
С другой стороны, существуют кучи, используемые для выделения памяти. Именно здесь выполняется вся бухгалтерия для распределения памяти кучи. Эти структуры сложны для минимизации конкуренции между потоками, поэтому некоторые потоки могут совместно использовать структуру кучи (арену), а некоторые могут использовать разные арены.
Для отличного объяснения деталей см. Следующий раздел: Как работает malloc в многопоточной среде?
Ответ 6
Как правило, потоки разделяют кучу и другие ресурсы, однако есть поточно-подобные конструкции, которые этого не делают. Среди этих нитевидных конструкций - легкие процессы Erlang и полноэкранные процессы UNIX (созданные при вызове fork()
). Вы также можете работать с несколькими машинами concurrency, и в этом случае ваши межпоточные параметры связи значительно ограничены.
Ответ 7
Вообще говоря, все потоки используют одно и то же адресное пространство и поэтому обычно имеют только одну кучу.
Однако это может быть немного сложнее. Возможно, вы ищете Thread Local Storage (TLS), но он сохраняет только одни значения.
Окна-Specific: TLS-пространство может быть выделено с помощью TlsAlloc и освобождено с помощью TlsFree (Обзор здесь). Опять же, это не куча, просто DWORDs.
Странно, Windows поддерживает несколько Heaps за процесс. Можно хранить рукоятку кучи в TLS. Тогда у вас будет что-то вроде "Thread-Local Heap". Тем не менее, только дескриптор не известен другим потокам, они все еще могут обращаться к своей памяти с помощью указателей, поскольку это все еще одно и то же адресное пространство.
EDIT: некоторые распределители памяти (в частности jemalloc на FreeBSD) используют TLS для назначения "арены" к потокам. Это делается для оптимизации распределения для нескольких ядер за счет сокращения накладных расходов на синхронизацию.
Ответ 8
В операционной системе FreeRTOS задачи (потоки) имеют одну и ту же кучу, но каждый из них имеет свой собственный стек. Это очень удобно при работе с низкомощными архитектурами с низким ОЗУ, поскольку один и тот же пул памяти может быть доступен/разделен несколькими потоками, но это связано с небольшим уловом, разработчик должен иметь в виду, что механизм синхронизации malloc и необходим бесплатный, поэтому необходимо использовать некоторый тип синхронизации/блокировки процесса при распределении или освобождении памяти в куче, например семафоре или мьютексе.