2014-11-16 2 views
1

Я пытаюсь создать два набора сегментов разделяемой памяти. Один для хранения целых чисел, а другой для хранения строк. Я получаю сообщение об ошибке во втором вызове shmget, когда я создаю сегмент разделяемой памяти для своих целых чисел.Второй shmget всегда возвращает доступ denied

keyS=5678; 
keyI=6789; 
    //create shared memory for titles and categories 
    if(stringsID=shmget(keyS,sizeof(char*)*lineCounter*2,IPC_CREAT|0666)<0) 
    { 
     perror("shmget"); 
     fprintf(stderr, "Titles Cannot create shared memory errno %i: %s\n",errno,strerror(errno)); 

     exit(-1); 
    } 

    //attach to shared memory 
    if ((titlesSH = (char**)shmat(stringsID, NULL, 0)) ==(char**) -1) 
    { 
     perror("shmat"); 
     exit(1); 
    } 

    //titles start at titlesSH[0] while categories start at titlesSH[lineCounter] 
    categoriesSH=titlesSH+lineCounter; 


    //create shared memory for stock and codes 
    if(intsID=shmget(keyI,sizeof(int)*lineCounter*2,IPC_CREAT|0666)<0) 
    { 
     perror("shmget"); 
     fprintf(stderr, "Stock Cannot create shared memory errno %i: %s\n",errno,strerror(errno)); 

     exit(-1); 
    } 
    //attach to shared memory 
    if((stockSH=(int*)shmat(intsID,NULL,0))==(int*)-1) 
    { 
     perror("shmat"); 
     exit(-1); 
    } 

Когда я бегу ipcs в терминале я вижу, что нет МПБХВ с ключами, которые я задающих в моем коде, но я пробовал разные ключи, и результат всегда один и тот же. Я делаю что-то неправильно?

Я попытался удалить 0666 от привилегий, когда я звоню shmget и делает остановки (shmget не возвращает -1) и давайте мое содержание копирования в России, но когда я пытаюсь получить содержимое из него я получаю ошибку сегментации.

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

** ИЗМЕНИТЬ обходное решение, о котором я говорил выше, в настоящее время работает Я храню все моя информация в одном сегменте разделяемой памяти, в котором хранятся строки, а размер - это сумма двух сегментов, которые я пытался создать. Таким образом, пространство общей памяти не является проблемой. ipcs только дает мне 9 МПБОВ работают, так что я полагаю, что предел МПХБА и предел пространства не проблема в этом случае

+1

Что говорит 'errno'? Сколько сегментов разделяемой памяти настроено для поддержки вашей системы? (Это вряд ли будет одним, но, возможно, другие уже используются.) Второй ключ уже используется какой-либо другой программой? Что показывает вам «ipcs»? При запуске 'root'? (Я вижу, вы говорите, что он ничего не показывает вам, и вы пытались изменить ключи с тем же эффектом.) Может ли это быть неудачным, потому что вы пытаетесь создать слишком _small_ сегмент? Является параметром ядра 'shmmin', и, возможно, набор целых чисел слишком мал? Я беспокоюсь о размере вашего строкового пространства. –

+0

Ну, это то, что я создаю указатели строк в ядре, а не фактические строки. теперь для максимального ipcs я не думаю, что я достигаю предела, учитывая, что я случайно запускал 5 разных программ одновременно, создавая такой же размер, как мой код выше разделяемой памяти, и он работает нормально. Если проблема не в том, что один процесс не может создать два разных сегмента разделяемой памяти.то, что у меня сейчас есть и работает, я объединил два сегмента в один со строками и конвертировал ints в строки перед их отправкой. Поэтому я предполагаю, что пространство с разделяемой памятью не является проблемой. –

+0

работает ipcs возвращает несколько ipcs, управляемых системными приложениями и моими. Всего байтов Mine со старым кодом было 32 (linecounter - 4, я создаю два указателя для каждой строки, так что общее число 32), а с новым кодом вдвое больше (поскольку снова я создаю только указатели строк). Но опять-таки общий предел пространства для ipcs это не проблема, поскольку я объединил два сегмента в одном и работает –

ответ

1

if(stringsID=shmget(keyS,sizeof(char*)*lineCounter*2,IPC_CREAT|0666)<0) 
/* and */ 
if(intsID=shmget(keyI,sizeof(int)*lineCounter*2,IPC_CREAT|0666)<0) 

Если, скорее всего, будет:

if((stringsID=shmget(keyS,sizeof(char*)*lineCounter*2,IPC_CREAT|0666)) < 0) 
/* and */ 
if((intsID=shmget(keyI,sizeof(int)*lineCounter*2,IPC_CREAT|0666)) <0) 

Для демонстрации,

  1. скомпилировать последовательные ng (выводит ли ваш компилятор какие-либо предупреждения? шахта делает)
  2. Выполнить это
  3. сделать ls -ltr
  4. запустить его снова
  5. сделать ls -ltr снова

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 

int main(void) { 

int fd; 

if (fd=open("omgwtf", O_RDWR|O_CREAT, 0644) < 0) { 
     fprintf(stderr, "WTF!\n"); } 

fprintf(stderr, "fd=%d\n", fd); 

return 0; 
} 

Примечание: для дополнительного удовольствия, вы можете добавить O_EXCL к флаги.

+1

Нет, это не так. Просто проверьте диаграмму приоритета. (эта ошибка чаще всего встречается с помощью 'open()', но она работает, конечно, с любым вызовом функции) – joop

+1

Забудьте мой последний комментарий, я прочитал их по-другому (вот почему я сказал, пожалуйста, опишите, поскольку это немного не читаемый, но все же моя первоначальная ошибка и). Да, именно это и вызывало мою ошибку –

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