| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > threads |
| Автор: Artemon 2.12.2007, 14:46 |
| 1. Есть класс 2. Есть внешняя ф-ия по отношению классу, но объявленная как friend Внутри класса создаю поток и в качестве параметра передаю ему ту самую внешнюю фию и сам экземпляр класса. Я в потоке улаляю переданный экземпляр класса и вродебы все нормально удаляется, ао крайнй мере управление передается в деструктор. На первый взгляд кажется все чинно, но вот попробовла подряд создать около 300 таких класов с потоками и вдруг мне Linux начал говорить что ему нехватает памяти на создание потока ? С чего бы это, ведь вроде потоки создаются и удаляются нормально, а памяти говорит не хватает. |
| Автор: JackYF 2.12.2007, 14:55 |
| Artemon, ну ты понял, код давай сюда |
| Автор: bsa 2.12.2007, 21:09 |
| Artemon, у тебя потоки NPTL или старые линуксовые? |
| Автор: MAKCim 2.12.2007, 21:29 |
| Artemon, давай сюда код в плане использования памяти разницы нет |
| Автор: bsa 3.12.2007, 13:10 |
| MAKCim, разве? я читал, что NPTL отличается тем, что не выполняется копирование страниц памяти процесса - значит память выделяется... Видимо, что-то не то читал... |
| Автор: bsa 3.12.2007, 14:11 |
| MAKCim, спасибо, буду знать. |
| Автор: xvr 3.12.2007, 15:31 | ||||
А сам поток при этом завершается? pthread_join вызывали или detached статус потоку ставили?
Память - да, а вот собственно потоки - неизвестно |
| Автор: vinick 5.12.2007, 13:18 | ||
Каждый поток имеет свой собственный стек, по умолчанию стек равен 8 метров. Получается если в какой-то момент у процесса оказалось 300 рабочих потоков, то только их стек занял 2.5 гига виртуальной памяти. Всего на 32-битной системе процесс может забрать около 3 гиг, кажется даже чуть меньше. Вот и получается нехватка памяти. |
| Автор: MAKCim 5.12.2007, 13:50 |
| vinick, в таком случае используется swap + стек расширяется динамически, по мере надобности |
| Автор: vinick 5.12.2007, 15:50 | ||||
Своп используется когда заканчивается физическая оперативная память. Я же говорю о виртуальном адресном пространстве процесса, когда оно заканчивается то получается out of memory. В 32-битных системах процесс может адресовать всего 4 гига памяти, но в linux около гига забирает ядро и по-моему что-то отдается загруженным динамическим библиотекам, итого процессу на личные нужды остается меньше 3 гиг. На каждый созданный поток по умолчанию резервируется 8 метров стека из этого адресного пространства, если потоков много, то их стек съедает все. Расширяемость стека к топику не относится. Но стало интересно Я не смог найти в сети ни подтверждений вашего тезиса ни опровержения. Но вот такой пример при ulimit -s == 8192 почучает ошибку сегментирования. Или стек надо какими-то системными вызовами принудительно расширять?
|
| Автор: bsa 5.12.2007, 16:06 | ||
Ядру гиг не нужен. Просто память некоторых устройств (видеокарт, например) отображается в адресное пространство процессора. Это приводит к тому, что когда установлено 4Гига памяти, часть из нее перекрывается отображаемой памятью. И это не только в Linux. |
| Автор: vinick 5.12.2007, 16:18 | ||
| bsa, цитата http://www.ibm.com/developerworks/ru/library/l-memmod/#N102ED
Не путайте физически установленную оперативную память и вирутальную память. Это немного разные вещи. |
| Автор: MAKCim 5.12.2007, 19:02 | ||||||||||||||
| vinick, вот мое маленькое исследование
далее смотрим /proc/3862/maps (PID = 3862)
получаем
7fff3e36c000 - 7fff3e355000 = 94208 байт далее посылаем процессу сигнал SIGUSR1
опять смотрим /proc/3862/maps
7fff3e36c000 - 7fff3e2e7000 = 544768 отсюда можно сделать однозначный вывод о расширении стека вниз и он будет расширяться, пока не будет достигнут лимит на его размер этот лимит равен ~ 8MB |
| Автор: Artemon 7.12.2007, 13:25 | ||
Код моего приложения примерно следующий:
|
| Автор: xvr 7.12.2007, 14:30 | ||||
Про create_thread попдробнее. Что вызывается и с какими параметрами? |
| Автор: Artemon 7.12.2007, 14:51 |
| Особых настроек здесь нет, только переменная для ID потока и собственно функция потока. |
| Автор: xvr 7.12.2007, 14:55 | ||||
Как ДОСЛОВНО называлась (и вызывалась) функция запуска thread'а ? |
| Автор: Artemon 7.12.2007, 16:31 |
| result = pthread_create(&tid, NULL, NetThread, (void*)this); |
| Автор: bsa 7.12.2007, 17:09 |
| Artemon, а где pthread_join? |
| Автор: vinick 7.12.2007, 17:16 | ||||
| Artemon, Потоки надо либо ловить с помощью pthread_join, либо отсоединять. Иначе все ресурсы занятые потоком не освобождаются после его завершения. В вашем коде проще всего отсоединять потоки. 1. Либо сразу после создания
2. Либо используя аттрибут PTHREAD_CREATE_DETACHED
|
| Автор: Artemon 19.12.2007, 10:01 |
| Всем спасибо, задача разрешилась. Особое спасибо vinickУ |