Нитками ділиться все [1]. Для всього процесу є один адресний простір.
Кожен потік має свій стек та регістри, але всі стеки потоків видно у спільному адресному просторі.
Якщо один потік виділяє якийсь об’єкт у своєму стеку і надсилає адресу в інший потік, вони обоє матимуть рівний доступ до цього об’єкта.
Насправді я щойно помітив більш широку проблему: я думаю, що ви плутаєте два вживання слова сегмент .
Формат файлу для виконуваного файлу (наприклад, ELF) має в ньому різні розділи, які можуть називатися сегментами, що містять скомпільований код (текст), ініціалізовані дані, символи посилання, інформацію про налагодження тощо. Немає сегментів купи або стека тут, оскільки це лише конструктивні режими.
Ці сегменти бінарних файлів можуть бути окремо відображені в адресному просторі процесу з різними дозволами (наприклад, виконуваний лише для читання код / текст та невиконаний при копіюванні на запис для ініціалізованих даних).
Області цього адресного простору використовуються для різних цілей, як розподіл купи та стеки потоків, за умовами (примусово виконуються вашими мовними бібліотеками виконання). Це все лише пам'ять, і, ймовірно, не сегментоване, якщо ви не працюєте у віртуальному режимі 8086. Кожен потік потоку - це фрагмент пам'яті, виділений під час створення потоку, з поточною верхньою адресою стека, що зберігається в регістрі вказівника стека, і кожен потік зберігає власний покажчик стека разом з іншими його регістрами.
[1] Добре, я знаю: сигнальні маски, TSS / TSD і т.д. Адресний простір, включаючи всі його відображені програмні сегменти, все ще спільний.