Memória compartilhada: shmget falha: Não há espaço no dispositivo - como aumentar os limites?

2

Eu chamo shmget muitas vezes no meu programa, para obter shm de tamanho médio de 85.840 bytes. Eu obtenho cerca de 32771 shm ok, então o shmget não retorna um shm, mas o erro: "Não há mais espaço no dispositivo".

Eu aumentei os limites do kernel para:

$ sysctl -A|grep shm
kernel.shmmax = 33554432
kernel.shmall = 1677721600
kernel.shmmni = 409600

Mas ainda assim recebo o problema. Por quê?

Eu tenho que colocar algo em /etc/security/limits.conf também? Eu só tenho "usuário - nofile 1000000" porque o programa também abre tantos arquivos quanto o shms.

Esta é a saída do livre

$ free
          total       used       free     shared    buffers     cached
Mem:       8150236    7261676     888560          0     488100    3270792
-/+ buffers/cache:    3502784    4647452 
Swap:     12287992     554692   11733300

E ipcs

$ ipcs -lm                                                                         

------ Shared Memory Limits --------
max number of segments = 409600
max seg size (kbytes) = 1638400
max total shared memory (kbytes) = 6710886400
min seg size (bytes) = 1

Como suponho que o shm é capaz de ser trocado, deve haver espaço suficiente.

    
por j13r 19.03.2012 / 11:24

3 respostas

3

Acontece que shmmni está limitado a 32768 no kernel:

#define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */

no arquivo ...version.../include/linux/ipc.h .

Tão curto de recompilar o kernel, esse é o limite rígido do número de segmentos de memória compartilhada.

    
por 20.03.2012 / 08:18
2

Use ipcs -l para verificar os limites realmente em vigor e ipcs -a e ipcs -m para ver o que está em uso, para que você possa comparar a saída. Observe a coluna nattch : há segmentos sem processos anexados que não foram removidos quando os processos foram encerrados (o que normalmente significa que o programa travou)? ipcrm pode eliminá-los, embora se for uma máquina de teste, a reinicialização será mais rápida (e garantirá que suas alterações nos limites sejam removidas).

Seus parâmetros do kernel parecem estranhos. Em particular, shmall é uma contagem de páginas, não de bytes, e 4kB é o tamanho de página padrão (execute getconf PAGESIZE para verificar o que você está usando). Quantos terabytes de RAM você tem?

Agora, você diz que obtém cerca de 32771 segmentos de memória compartilhada, que também é cerca de 32768 (ou 2 a 15), o que sugere que um int de 16 bits com sinal é o fator limitante. E qual kernel você está executando (pois isso terá seus próprios limites)? Os dois podem estar relacionados.

    
por 19.03.2012 / 12:14
0

Como shmget() aloca um novo segmento de memória compartilhada, e você parece usar muitos deles (considerando seu limits.conf), não é possível que você esteja usando muitos segmentos de memória compartilhada? Eu não tenho muita experiência em chamar shmget() , mas parece-me que o número de possíveis arquivos abertos (1000000) é maior que a quantidade de segmentos de memória compartilhada permitidos (SHMMNI), que é 409600.

    
por 19.03.2012 / 11:53

Tags