2012-01-19 4 views
1

экспериментирует с shm_open в Linux и сталкивается с проблемами. Я часто изменяю размер сегмента разделяемой памяти с помощью ftrunc и используя mmap для переназначения сегмента с измененным размером. однако, около 20 мегабайт, я получаю ENOMEM от mmap.mmap возвращает ENOMEM с файлом shm_open

вещей я пытался сделать, чтобы решить эту проблему:

первой, я узнал об этих параметрах SYSCTL. я перенастроить их:

kernel.shmmax = 268435456 
kernel.shmall = 2097152 

(SHMALL указывается в страницах)

проблема все еще произошло после этого. исследуя детали изменения размера, вызывающего проблему, выяснилось, что вызов, сделанный для ftrunc для изменения размера объекта общей памяти, преуспел (соответствующий файл в/dev/shm имел запрошенный новый размер).

документация здесь http://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html предлагает три возможные причины в ENOMEM егто:


[ENOMEM] MAP_FIXED был определен, и диапазон [адр, адр + длина) превышает, что позволило для адресного пространства процесс; или, если MAP_FIXED не был указан и в адресном пространстве недостаточно места для осуществления сопоставления.

[ENOMEM] [ML] [Option Start] Отображение невозможно заблокировать в памяти, если требуется mlockall(), поскольку для этого потребуется больше места, чем может обеспечить система. [Опция завершена]

[ENOMEM] [TYM] [Option Start] Недостаточно нераспределенных ресурсов памяти остаются в типизированном объекте памяти, указанном fildes, для выделения len байтов. [Вариант Конец]


я не использую MAP_FIXED или замок, и размер изображения в/DEV/шм предполагает, что третья причина не является проблемой. мой ММАП вызов выглядит следующим образом:

ММАП (мем, длина PROT_READ | PROT_WRITE, MAP_SHARED Ф.Д., 0)

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

Я нашел информацию о том, что настройки ulimit могут ограничивать память, отображаемую в один процесс, но я не думаю, что проблема была здесь. только в том случае, ULIMIT -a выглядит, как это на моей машине:

core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 20 
file size    (blocks, -f) unlimited 
pending signals     (-i) 16382 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 65536 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) unlimited 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

я надеюсь, что это легкий один :)

+1

Шрифты 'shmmax' и' shmall' sysctl предназначены для SysV SHM, а не POSIX SHM. –

ответ

1

хорошо, я узнал, что моя проблема была в другой день. я неправильно читаю документацию для mmap, в которой говорится, что mmap возвращает отображение на основе первого параметра (ранее сопоставленного адреса в моем случае), и результат определяется реализацией. я воспринял это как предложение о том, что mmap может переназначить мое предыдущее сопоставление для меня, но это, безусловно, не так. это могло произойти только в том случае, если я использовал флаг MAP_FIXED, но я избегал этого, потому что рекомендованная к нему документация. в любом случае, необходимо было использовать munmap для удаления предыдущего сопоставления перед созданием нового.Я надеюсь, что этот пост поможет любому, кто сделал бы такое же глупое неправильное чтение, что и я.

Смежные вопросы