LINUX.ORG.RU

создание потока и раскладка потока


0

0

Правильно ли я понимаю, что когда создается поток для него создается только стек? Сегмент кода, данных (инициализированных и неинициализированных) и куча не создаются? Последние три на процесс.

Есть еще thread-local переменные. Т.е. для каждого потока свой экземпляр переменной.

eXire ★★ ()

Куча может и создаваться - это зависит от аллокатора. Аллокации в куче, локальной для нити, делаются быстрее, чем в общей куче, т.к. не надо лишних блокировок и ожиданий.

Для нити также создаются объекты в ядре.

dmitry_vk ★★★ ()

>>Правильно ли я понимаю, что когда создается поток для него создается только стек?

Да.

Сегмент кода, данных (инициализированных и неинициализированных) и куча не создаются?

Не создаются. Куча всегда одна на процесс (мы сейчас говорим о линаксе и С/С++, в некоторых языках может быть по-другому), и издержки при доступе к ней неминуемы. Некоторые аллокаторы делят кучу на зоны - одна под каждый процесс, но это жёсткий костыль, так как тред всё равно имеет доступ ко всей куче.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Куча всегда одна на процесс (мы сейчас говорим о линаксе и С/С++, в некоторых языках может быть по-другому),

ссылку на пункты стандартов си и с++

и издержки при доступе к ней неминуемы.

не лез бы ты со своим маркетоидным бредом в девелопмент, а?

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>ссылку на пункты стандартов си и с++

Спецификации языков не говорят ничего про потоки. А на практике - да, обычно куча одна, чтобы была не одна нужны телодвижения различной степени тяжести.

legolegs ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>>ссылку на пункты стандартов си и с++

Причем тут С/С++? Во-первых, в стандарте этих языков не сказано, как выделяется память на потоки и про потоки вообще. Удивил тебя? Во-вторых, так как С/С++ - компилируемые языки, то память в них выделяется через системные вызовы - читай до посинения про brk и про потоки/процессы в линаксе вообще (особенно про их адресное пространство). Выделять отдельную кучу на поток могут языки, которые используют виртуальные машины (типа Java) - там это можно реализовать. Как ты будешь это реализовывать в линаксе - я посмотрю.

и издержки при доступе к ней неминуемы.

Прочитай про блокировки при выделении/удалении памяти и не позорься.

не лез бы ты со своим маркетоидным бредом в девелопмент, а?

Сынок, не лез бы ты во взрослые разговоры. Тут серьезные дяди общаются.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Как ты будешь это реализовывать в линаксе - я посмотрю.

если твои поврежденные managed-языками мозги не осиливают способ реализации таких аллокаторов для с/с++ — это не значит, что они невозможны

вот например http://goog-perftools.sourceforge.net/doc/tcmalloc.html

юзается чисто через LD_PRELOAD=«/usr/lib/libtcmalloc.so»

при этом держит (для мелких аллокаций) СВОЙ кэш на каждую нить, и думаю полностью не разделяет память между нитями только затем, чтобы удобнее было укладывать крупные куски

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Сынок, не лез бы ты во взрослые разговоры. Тут серьезные дяди общаются.

уж лучше пусть мы будем общаться, чем такие безграмотные дяди

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>>если твои поврежденные managed-языками мозги не осиливают способ реализации таких аллокаторов для с/с++ — это не значит, что они невозможны

А ты смешной клоун. Если бы ты разбирался в теме, то знал бы, что в реализованной в линаксе системе потоков нельзя реализовать отдельные кучи для потоков по ОПРЕДЕЛЕНИЮ. То, что ты мне тут показал - те же яйца, только вид сбоку.

при этом держит (для мелких аллокаций) СВОЙ кэш на каждую нить,

А теперь я внимательным образом слушаю твои потуги объяснить, каким способом это реализовано. Меня терзают смутные сомнения, что эти локальные для тредов кэши выделяются в той же самой общей куче. Профит в данной случае в том, что убираются лишние блокировки при выделении/освобождении памяти - каждый тред обращается к своему куску кучи и не нужно блокировать на это время другие треды. Разделяемые библиотеки используют кучу самого процесса.

P.S. Я тебе настоятельно рекомендую прочитать про то, как реализованы треды в линаксе, как реализовано выделение памяти процессу. Тогда ты не будешь так жестко позориться.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Если бы ты разбирался в теме, то знал бы, что в реализованной в линаксе системе потоков нельзя реализовать отдельные кучи для потоков по ОПРЕДЕЛЕНИЮ.

А теперь я внимательным образом слушаю твои потуги объяснить, каким

способом это реализовано.

ссылку я уже дал, ищи дальше сам

Меня терзают смутные сомнения, что эти локальные для тредов кэши выделяются в той же самой общей куче.

пойди уж прочти...

Objects are moved from central data structures into a thread-local cache as needed, and periodic garbage collections are used to migrate memory back from a thread-local cache into the central data structures.

... или хотя бы картинки посмотри, дядя — там они есть :-)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>>ссылку я уже дал, ищи дальше сам

Я прочитал, оно лишь подтвердило мои предположения.

Objects are moved from central data structures into a thread-local cache as needed, and periodic garbage collections are used to migrate memory back from a thread-local cache into the central data structures.

Хорошо, я заметил, что ты туго думаешь. Зайдем с другой стороны. Ответь мне прямо и четко: где размещается в памяти thread-local cache для каждого треда? Дам тебе подсказку: сегмент данных общий у всех тредов. Другой способ выделить память - анонимный mmap. Но это явно не катит, потому что у меня может вообще не быть свопа. Так что я внимательно слушаю твою версию.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>>... или хотя бы картинки посмотри, дядя — там они есть :-)

Я так понял, ты в архитектуре юникса вообще не разбираешься, раз судишь о работе аллокатора памяти по картинкам.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> где размещается в памяти thread-local cache для каждого треда?

thread-local storage ?

Дам тебе подсказку: сегмент данных общий у всех тредов.


и что?

Другой способ выделить память - анонимный mmap.


другой по сравнению с чем?

Но это явно не катит, потому что у меня может вообще не быть свопа


и после этого ты называешь кого-то клоуном?

idle ★★★★★ ()
Ответ на: комментарий от idle

>>thread-local storage ?

А где он располагается в памяти? Скоро мы все-таки дойдем до того момента, когда станет ясно, что всё хранится в общей куче. У треда есть только один способ хранения локальных переменных - стек.

Дам тебе подсказку: сегмент данных общий у всех тредов.

и что?

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

Другой способ выделить память - анонимный mmap.

другой по сравнению с чем?

Слушайте, вы тут на пару что ли теперь затупать собрались? Ладно, я сегодня добрый. Есть два способа выделить память для процесса: посредством brk() и посредством анонимного mmap. Другого не дано.

Но это явно не катит, потому что у меня может вообще не быть свопа

и после этого ты называешь кого-то клоуном?

Сынок, ты хоть про mmap() читал или тоже, как и предыдущий, рассматривал картинки? Ладно, я же говорил, что добрый сегодня, расскажу. Анонимный mmap отображается на своп, потому что при нехватке памяти это отображение надо будет куда-то сохранять для освобождения места. А если свопа нет в системе, то куда ядро денет это отображение? Правильно, оно не даст его тебе даже создать. Так кто там главный клоун из вас двоих?

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> >>thread-local storage ?



А где он располагается в памяти? Скоро мы все-таки дойдем до того


момента, когда станет ясно, что всё хранится в общей куче.



ессно, ->mm у всех потоков общий. и что? вы просто не понимаете
о чем идет речь.

У треда есть только один способ хранения локальных переменных - стек.


стек тоже в общей памяти, что не мешает использовать его как
thread-local память.

>>> Дам тебе подсказку: сегмент данных общий у всех тредов.



>>и что?




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


кроме стека нет.



см выше.

>>> Другой способ выделить память - анонимный mmap.



>>другой по сравнению с чем?




Слушайте, вы тут на пару что ли теперь затупать собрались? Ладно,


я сегодня добрый.



нам повезло!

Есть два способа выделить память для процесса:

посредством brk() и посредством анонимного mmap.



это, на самом деле, один способ. brk() это тот же mmpap() c неявными
параметрами MAP_FIXED и addr = brk - task->mm->brk.

>>> Но это явно не катит, потому что у меня может вообще не быть

свопа




>>и после этого ты называешь кого-то клоуном?




Сынок, ты хоть про mmap() читал или тоже, как и предыдущий,


рассматривал картинки?



не читал, дяденька. вы не поверите, но есть и другие способы знать,
как работает код.

Ладно, я же говорил, что добрый сегодня, расскажу.

А если свопа нет в системе... оно не даст его тебе даже создать.



проверяли? MAP_PRIVATE | MAP_ANONYMOUS не работает после swapoff, да?

Так кто там главный клоун из вас двоих?


в вот проверьте и сделайте выводы.

idle ★★★★★ ()

я не поленился и проверил

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define N (16*1024*1024)

int main(int argc, char *argv[])
{
    int fd = -1;
    unsigned int *map = (unsigned int *) mmap(0, N*sizeof(int), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
    if (map == MAP_FAILED) {
        perror("mmap error");
        exit(EXIT_FAILURE);
    }
    unsigned int sum=0, val=1;
    for(unsigned int i=0; i<N; i++) { // writing
        map[i]=val;
        val+=val<<2; 
    }
    for(unsigned int j=0; j<N; j++) // reading
        sum+=map[j];
    printf("4*sum+1            = %u \n", 4*sum+1);
    printf("and must be equal to %u \n", val);
    return 0;
}

делаю swapoff -a и все работает (проверяю cat /proc/swaps)

вообще идея о том, что нельзя никак заставить mmap работать без свопа это явный признак... ну если быть политкорректным, то излишнего напряжения на работе.

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

компилялось без оптимизации, чтобы жцц не пытался объединять циклы

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от idle

>>ессно, ->mm у всех потоков общий. и что? вы просто не понимаете о чем идет речь.

Я прекрасно понимаю суть вопроса, но вы меня сейчас пытаетесь убедить, что костыли являются чем-то новым и неожиданным.

стек тоже в общей памяти, что не мешает использовать его как

thread-local память.

В общей памяти чего? Процесса?

это, на самом деле, один способ. brk() это тот же mmpap() c неявными

параметрами MAP_FIXED и addr = brk - task->mm->brk.

Не стоит нести такую чушь. brk() изменяет границу сегмента данных, mmap() же присоединяет страницы к виртуальному адресному пространству процесса. Разницу чувствуешь?

проверяли? MAP_PRIVATE | MAP_ANONYMOUS не работает после swapoff, да?

Это зависит от реализации, потому что анонимный маппинг не входит в посикс.

в вот проверьте и сделайте выводы.

Я уже давно их сделал, итак все понятно. Но вы не хотите понять самой проблемы - в линаксе нельзя выделить потоку приватнвй кусок памяти кроме, как на стеке. Даже тот же анонимный маппинг цепляет страницы к ПРОЦЕССУ, а значит эти страницы доступны всем тредам. И куча на всех одна. Поэтому я уже конкретно вас спрашиваю: каким образом кроме стека выделить треду приватную память?

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Анонимный mmap отображается на своп, потому что при нехватке памяти это отображение надо будет куда-то сохранять для освобождения места. А если свопа нет в системе, то куда ядро денет это отображение? Правильно, оно не даст его тебе даже создать.

Зря ты в Девел полез, мужик.

tailgunner ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

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

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

>>Зря ты в Девел полез, мужик.

См. выше

Про отдельные кучи для нитей ты тоже облажался - ты просто не понимаешь, что это такое.

Хотя с анонимным маппингом ты облажался больше. Вообще, хорошо, что ты к нам зашел. Теперь всем ясно, чего ты стоишь.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

>>Про отдельные кучи для нитей ты тоже облажался - ты просто не понимаешь, что это такое.

Давай конкретно, что я сказал не так по поводу нитей. Чтобы четко и ясно, а не так: «ты облажался, но мне это приснилось вчера». Я жду конкретики. Иначе пахнет высером. Я вообще не вижу конкретики в треде - все что-то говорят, но в общих чертах. Я уже устал спрашивать, где в памяти выделяется место под эти локальные хранилища.

Хотя с анонимным маппингом ты облажался больше. Вообще, хорошо, что ты к нам зашел. Теперь всем ясно, чего ты стоишь.

Я привел ПРИМЕР того, как этот маппинг может быть реализован. Стандарта на него нет - значит, реализация внутренняя может быть любой. Еще раз - это не снимает сути вопроса - каким способом ты собрался выделять треду приватную память. Я жду твоей версии ответа, если, конечно, ты что-то знаешь и умеешь кроме того, как чесать языком.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

Твоим образованием я заниматься не собираюсь. Хочешь заняться самообразованием - можешь начать со статей Дреппера о работе памяти. Может, поймешь, что такое локальность.

если, конечно, ты что-то знаешь и умеешь кроме того, как чесать языком.

На «слабо» еще кто-то ведется?

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

>>Твоим образованием я заниматься не собираюсь. Хочешь заняться самообразованием - можешь начать со статей Дреппера о работе памяти. Может, поймешь, что такое локальность.

Я в курсе, что такое локальность. Разговор шел о выделении треду приватной памяти.

На «слабо» еще кто-то ведется?

Высер засчитан, не вопрос.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от tailgunner

Дреппер - это тот фанатик с редхата что ли?

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Я в курсе, что такое локальность.

Совсем недавно ты был в курсе, что анонимный маппинг не работает без свопа.

На «слабо» еще кто-то ведется?

Высер засчитан, не вопрос.

«Я знал, что ты это скажешь» (с)

Дреппер - это тот фанатик с редхата что ли?

Ты не знаешь точно, кто такой Дреппер? O_o Расскажи о себе еще что-нибудь.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

>>Совсем недавно ты был в курсе, что анонимный маппинг не работает без свопа.

Ты дурак или прикидываешься? Я тебе привел пример, почему этот вариант не всегда может покатить. Я там написал, что конкретно в линаксе без свопа не работает? Нет. Где-то анонимный маппинг вообще на девайс можно замаппить может, и что? Тогда нефиг чушь пороть.

«Я знал, что ты это скажешь» (с)

Да понял я, что ты пукнул, понял. Можешь больше не раздувать запах.

Ты не знаешь точно, кто такой Дреппер? O_o Расскажи о себе еще что-нибудь.

Мне на него с высокой колокольни, если честно. От того, что я его буду знать, мне денег не прибавится. Так это тот неадекват или нет?

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Разговор шел о выделении треду приватной памяти.

это ты так считаешь исходя из каких-то странных логических связей в своем мозге; обсуждение началось с того, что ты сказал:

и издержки при доступе к ней неминуемы.

а затем уточнил, что за издержки:

Прочитай про блокировки при выделении/удалении памяти и не позорься.

подумай над тем, что память может быть не «приватная» в твоей терминологии, но тем не менее издержки на блокировку отсутствуют

З.Ы. iZEN хоть и несет чушь иногда, но делает это в отличие от тебя вежливо

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Я там написал, что конкретно в линаксе без свопа не работает?

Ну, приведи Unix-систему, на которой это не работает.

Ты не знаешь точно, кто такой Дреппер?

Мне на него с высокой колокольни

Это понятно. Поэтому ты и останешься малограмотным троллем, который пытается неуклюже выпутаться из глупой ситуации, в которую попал по собственной самоуверенности.

tailgunner ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

>>а затем уточнил, что за издержки

Давай ты не будешь выдергивать мои фразы из контекста? Я сказал, что куча на все треды может быть только одна. Ты сметанировал, что это, дескать не так, и какая-то либочка умеет для тредов делать отдельные куски памяти и даже синхронизировать их с кучей, о чем ты узнал из занимательных картинок. Ясно дело, что ты спорол чушь, куда я и ткнул тебя носом.

подумай над тем, что память может быть не «приватная» в твоей терминологии, но тем не менее издержки на блокировку отсутствуют

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

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от tailgunner

>>Ну, приведи Unix-систему, на которой это не работает.

Следя твоей логике, ты должен сам заниматься самообразованием. Посмотри в сторону миникса, прикрутили там маппинг уже или нет.

Это понятно. Поэтому ты и останешься малограмотным троллем, который пытается неуклюже выпутаться из глупой ситуации, в которую попал по собственной самоуверенности.

Сказал великий метанатор.

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Я прекрасно понимаю суть вопроса, но вы меня сейчас пытаетесь

убедить, что костыли являются чем-то новым и неожиданным.


даже не знаю, что сказать

>>стек тоже в общей памяти, что не мешает использовать его

как thread-local память.




В общей памяти чего? Процесса?



да

>>это, на самом деле, один способ. brk() это тот же mmpap()

c неявными параметрами MAP_FIXED и addr = brk - task->mm->brk.




Не стоит нести такую чушь.



я все-таки попытаюсь ;)

brk() изменяет границу сегмента данных,


ерунда. непонятно, что вы в данном случае понимаете под
сегментом данных и его границей, но в любом случае вы
понимаете неправильно.

единственная «граница» о которой имеет смысл говорить
в этом контексте - это TASK_SIZE, она не меняется.
сегмента данных, как такового, не существует. но, разумеется,
вы можете придумать свое определение.

на всякий случай... пожалуйста, не пытайтесь мне рассказывать
про сегментные регистры, не надо.

mmap() же присоединяет

страницы к виртуальному адресному пространству процесса.


Разницу чувствуешь?



нет. с точки зрения vm - это одно и то же. brk() имеет смысл
как syscall, но по другим причинам.

>>проверяли? MAP_PRIVATE | MAP_ANONYMOUS не работает после

swapoff, да?




Это зависит от реализации, потому что анонимный маппинг не


входит в посикс.



ага. то есть, выводы вы делать отказываетесь.

в линаксе нельзя выделить потоку приватнвй кусок памяти кроме,

как на стеке.


...


анонимный маппинг цепляет страницы к ПРОЦЕССУ


...


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



похоже, вы к тому же не понимаете, что стек - это тот же
самый анонимный маппинг?

и снова, на всякий случай... да, я знаю про VM_GROWSDOWN/UP.


что касается остального... вам тут уже все обьяснили много раз.
но, по непонятной причине (не осмелюсь озвучивать мою гипотезу),
вы ничего понять не можете.

idle ★★★★★ ()
Ответ на: комментарий от idle

>>единственная «граница» о которой имеет смысл говорить в этом контексте - это TASK_SIZE, она не меняется. сегмента данных, как такового, не существует. но, разумеется, вы можете придумать свое определение.

Чтобы доползти до этой границы, надо сперва память выделить. Я об этом.

на всякий случай... пожалуйста, не пытайтесь мне рассказывать

про сегментные регистры, не надо.

причем они тут?

похоже, вы к тому же не понимаете, что стек - это тот же

самый анонимный маппинг?

Понимаю. Только у каждого треда этот стек будет находиться в своем юзерспейсе, и другой тред в этот стек не залезет.

и снова, на всякий случай... да, я знаю про VM_GROWSDOWN/UP.

уже неплохо

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

я полагал эту ученую дискуссию законченной, но я ошибался.

Только у каждого треда этот стек будет находиться в своем юзерспейсе


ну-ссс... я просто сгораю от нетерпения узнать об ЭТОМ
побольше. я надеюсь, сегодня вы такой же добрый?

>>и снова, на всякий случай... да, я знаю про VM_GROWSDOWN/UP.



уже неплохо



ух ты. меня больше не называют дураком и клоуном!
я «расту над собой».

idle ★★★★★ ()
Ответ на: комментарий от idle

>>ну-ссс... я просто сгораю от нетерпения узнать об ЭТОМ побольше. я надеюсь, сегодня вы такой же добрый?

Прочитай про адресное пространство процесса. Что тут не понятного именно?

MuZHiK-2 ★★★★ ()
Ответ на: комментарий от MuZHiK-2

> Прочитай про адресное пространство процесса

это... мне даже неловко это повторять, но тем не менее.
о том, как устроены обсуждаемые вещи я знаю вовсе не из
документации или популярных статей.

тем не менее - готов последовать совету. что конкретно
я должен прочитать в данном случае?

Что тут не понятного именно?


все непонятно. что такое «свой юзерспейс» ?
как это стек «будет находиться» в нем?

idle ★★★★★ ()
Ответ на: комментарий от idle

>>тем не менее - готов последовать совету. что конкретно я должен прочитать в данном случае?

То, что тебе сейчас непонятно, очевидно же.

все непонятно. что такое «свой юзерспейс» ?

виртуальное адресное пространство процесса. и имею ввиду не расшаренные с другими процессами страницы памяти.

как это стек «будет находиться» в нем?

значит стек будет находиться в виртуальном адресном пространстве процесса, указанном выше.

MuZHiK-2 ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.