Чи мають нитки чітку купу?


114

Наскільки мені відомо, кожен потік отримує чіткий стек, коли нитка створена операційною системою. Цікаво, чи кожна з ниток також відрізняє купу?


так, windows та linux, c library

3
Приємно. +1 продовжуйте залишати ті основні питання.

Відповіді:


128

Ні. Усі нитки мають спільну купу.

Кожна нитка має приватний стек , до якого можна швидко додавати та видаляти елементи. Це робить пам'ять на основі стека швидкою, але якщо ви використовуєте занадто багато пам'яті стека, як це відбувається в нескінченній рекурсії, ви отримаєте переповнення стека.

Оскільки всі потоки мають однакову групу, доступ до розподільника / оператора повинен бути синхронізований. Існують різні методи та бібліотеки для уникнення суперечок розподільника .

Деякі мови дозволяють створювати приватні пули пам’яті або окремі купи, які ви можете призначити одному потоку.


5
Зазвичай потоки діляться ресурсами, такими як пам'ять, тому будь-яка реалізація потоків, що не належать до мозку, поділила б купу.
Р. Мартіньо Фернандес

10
Основна причина , кожен потік має свій власний стек так , що потік може зробити що - то (наприклад , виклик функції а) ...
Едмунд

3
Кожна нитка має окремий стек, але це не обов'язково "приватний". Інші потоки зазвичай мають доступ до нього.
zch

you will get a stack overflow.Переповнення стека на Stack Overflow!
Джон Строд

2
@crisron Можна налаштувати окрему купу для кожного потоку, але якщо ви це зробите, а не використовуєте загальну групу за замовчуванням, то, наприклад, для потоку A виділити буфер, заповнити його даними, передати його в нитку B стає важко. , і мають потік B використовувати дані, а потім звільнити буфер (оскільки потік B не має доступу до купи потоку A, потік B не може звільнити буфер; найкращий потік B міг зробити це передати буфер назад до потоку A знову і майте нитку A безкоштовно це).
Джеремі Фріснер

9

За замовчуванням C має лише одну купу.

З цього приводу, деякі алокатори, які знають потоки, поділять купу, щоб у кожного потоку була виділена власна область. Ідея полягає в тому, що це повинно покращити масштаб купи.

Одним із прикладів такої купи є Хоард .


За замовчуванням C і C ++ не мають декількох потоків. Специфікація c ++ 2003 року, принаймні, не враховує потоки в її віртуальній машинній конструкції, тому потоки в c ++ визначаються реалізацією.
Кріс Бекк

Навіть якщо різні потоки мають різні ділянки для виділення на купі, вони все ще можуть бачити дані, виділені іншим потоком, тому нитки все ще діляться однаковою купою.
Кен Блум

1
Оновлення: станом на C ++ 11 потоки більше не визначені.
Майкл Дорст

5

Залежить від ОС. Стандартний час виконання c для Windows та Unices використовує спільну купу по потоках. Це означає заблокувати кожен малак / вільний.

Наприклад, у Symbian кожен потік має свою власну купу, хоча потоки можуть обмінюватися покажчиками на дані, виділені в будь-якій купі. На мою думку, дизайн Symbian є кращим, оскільки він не тільки виключає необхідність блокування під час allo / free, але також заохочує чітку специфікацію права власності на дані серед потоків. Також у тому випадку, коли нитка відмирає, вона бере всі виділені разом із нею об’єкти - тобто вона не може просочувати виділені нею об'єкти, що є важливою властивістю мати в мобільних пристроях із обмеженою пам'яттю.

Ерланг також дотримується подібної конструкції, коли «процес» виступає як одиниця збору сміття. Усі дані передаються між процесами шляхом копіювання, за винятком бінарних крапок, які посилаються на посилання (я думаю).


3

Кожен потік має свій стек і стек викликів.

Кожна нитка розділяє ту саму купу.


3

Це залежить від того, що саме ви маєте на увазі, говорячи "купи".

Усі потоки поділяють адресний простір, тому об'єкти, виділені з купи, доступні з усіх потоків. У технічному плані стеки поділяються також у цьому сенсі, тобто ніщо не заважає вам отримати доступ до стека інших потоків (хоча це майже ніколи не має сенсу).

З іншого боку, є купа структур , що використовуються для виділення пам'яті. Саме тут і ведеться вся бухгалтерія з розподілу пам'яті купи. Ці структури є складно організованими, щоб мінімізувати суперечки між нитками - тому деякі потоки можуть мати спільну структуру (арену), а деякі можуть використовувати окремі арени.
Дивіться наступну нитку для відмінного пояснення деталей: Як працює malloc у багатопотоковому середовищі?


1

Зазвичай нитки діляться нагромадженням та іншими ресурсами, однак є ниткоподібні конструкції, які цього не роблять. Серед цих ниткоподібних конструкцій - легкі процеси Ерланга та повні процеси UNIX (створені із закликом до fork()). Можливо, ви також працюєте над одночасністю багатомашинних версій, і в цьому випадку ваші варіанти комунікації між потоками значно обмежені.


Я думав, що форк більше нагадує створення нового процесу, який просто скопіював дані в нове місце пам'яті.
Джейсон Толструп

2
fork () може служити у багатьох випадках використання, коли також можуть використовуватися нитки. Завдяки копіюванню під час запису суттєва різниця у витратах на системи Unix. Типовим випадком використання є те, коли працівник є автономним (як веб-сервер) від решти послуг. Інша можливість полягає в спілкуванні через stdin / out з основним потоком / програмою. fork () є сильним для Unix, тоді як інші платформи, такі як Windows, віддають перевагу потоковій роботі. Основна причина, ймовірно, полягає в тому, що використання fork () набагато простіше і безпечніше, і Unix має цю філософію простоти. Дивіться, наприклад, веб-сервер apache з його повільним переходом до потоків.
ypnos

1

Взагалі кажучи, всі потоки використовують один і той же адресний простір і тому зазвичай мають лише одну купу.

Однак це може бути трохи складніше. Ви можете шукати локальне зберігання потоків (TLS), але воно зберігає лише окремі значення.

Спеціально для Windows: TLS-простір можна виділити за допомогою TlsAlloc та звільнити за допомогою TlsFree (Огляд тут ). Знову ж таки, це не купа, а лише DWORD.

Як не дивно, Windows підтримує кілька Купи в процесі. Ручку Heap можна зберігати в TLS. Тоді у вас вийшло б щось на кшталт "Тема-локальна купа". Однак просто ручка не відома іншим потокам, вони все ще можуть отримати доступ до її пам'яті за допомогою покажчиків, оскільки це все той же адресний простір.

EDIT : Деякі алокатори пам'яті (зокрема jemalloc у FreeBSD) використовують TLS для присвоєння "арен" потокам. Це робиться для оптимізації розподілу для декількох ядер шляхом зменшення накладних витрат синхронізації.


> "Як не дивно, Windows підтримує декілька груп на кожен процес.", Це зовсім не дивно, можна використовувати різні купи для різних типів виділень, просто додає більше гнучкості. Звичайно, ви завжди можете перейти до VirtualAlloc та створити власну купу, скільки захочете.

1

У операційній системі FreeRTOS завдання (потоки) поділяють ту саму купу, але кожна з них має власний стек. Це дуже зручно при роботі з архітектурами з низькою потужністю оперативної пам’яті з низькою потужністю, оскільки до одного і того ж пулу пам’яті можна отримати доступ / поділитися декількома потоками, але це має невеликий улов, розробнику потрібно пам’ятати, що існує механізм синхронізації malloc і вільний потрібен, тому необхідно використовувати певний тип синхронізації / блокування процесу при розподілі або звільненні пам'яті на купі, наприклад, семафорі або мютекс.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.