pthread_create завершается неудачно с ENOMEM в сценарии с нехваткой свободной памяти - PullRequest
3 голосов
/ 24 августа 2011

У меня есть плата SH4, вот характеристики ...

uname -a
Linux LINUX7109 2.6.23.17_stm23_A18B-HMP_7109-STSDK #1 PREEMPT Fri Aug 6 16:08:19 ART 2010
sh4 unknown

и предположим, что я съел почти всю память, и осталось только 9 МБ.

free
 total       used       free     shared    buffers     cached
Mem:         48072      42276       5796          0        172       3264
-/+ buffers/cache:      38840       9232
Swap:            0          0          0

Теперь, когда я пытаюсь запустить один поток с размером стека по умолчанию (8 МБ) pthread_create завершается с ENOMEM. Если я выполнил тестовый код, я вижу, что эта функция не работает, это mmap:

old_mmap(NULL, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC,                       
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

Однако, когда я устанавливаю размер стека на более низкое значение, используя ulimit -s:

ulimit -s 7500

Теперь я могу запустить 10 потоков. Каждый поток ничего не выделяет, поэтому потребляет только минимальные накладные расходы (приблизительно 8 кбайт на поток, верно?).

Итак, мой вопрос:

Зная, что mmap на самом деле не потребляет память, Почему pthread_create () (или mmap) не работает, если объем доступной памяти ниже размер стека потока?

Ответы [ 4 ]

6 голосов
/ 24 августа 2011

Параметр виртуальной машины /proc/sys/vm/overcommit_memory (он же. sysctl vm.overcommit_memory) определяет, желает ли Linux выдать больше адресного пространства, чем объединенный обмен ОЗУ + компьютера.(Конечно, если вы на самом деле попытаетесь получить доступ к такому объему памяти, что-то произойдет сбой. Попробуйте выполнить поиск по "linux oom-killer" ...)

Значение по умолчанию для этого параметра:0. Я собираюсь предположить, что кто-то установил это на что-то другое в вашей системе.

3 голосов
/ 24 августа 2011

В glibc размер стека по умолчанию для потоков равен 2-10 мегабайт (часто 8).Вы должны использовать pthread_attr_setstacksize и вызвать pthread_create с полученным объектом атрибутов, чтобы запросить поток с меньшим стеком.

2 голосов
/ 24 августа 2011

mmap потребляют адресное пространство .

Указатели должны однозначно идентифицировать часть «памяти» (включая файл mmap) в памяти.

32-битуказатель может адресовать только 2/3 ГБ памяти (32 бита = 2 ^ 32 = 4 ГБ. Но некоторое адресное пространство зарезервировано ядром).Это адресное пространство ограничено.

Все потоки в процессе используют одно и то же адресное пространство, но разные процессы имеют отдельные адресные пространства.

0 голосов
/ 24 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...