第二个shmget总是返回拒绝访问

时间:2014-11-16 15:26:53

标签: c ipc shared-memory

我正在尝试创建两组共享内存段。一个用于存储整数,另一个用于存储字符串。 当我为整数创建共享内存段时,我在第二次shmget调用时遇到错误。

 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时,我看到没有ipcs,我在代码中指定了键,但我尝试了不同的键,结果总是一样的。我做错了吗?

我在调用0666时尝试从权限中删除shmget并且它确实停止了(shmget没有返回-1)并且让我的副本内容在但是当我试图获取时它的内容我得到了一个分段错误。

如果我删除额外的共享内存段并保持只有一个一切正常。我知道有一个解决方法(将所有内容作为字符串存储在一个更大的内存段中)但我也想知道为什么会发生这种情况

**编辑我上面提到的解决方法目前正在运行 我将所有信息存储在一个存储字符串的共享内存段中,它的大小是我试图创建的两个段的总和。因此共享内存空间不是问题。 ipcs只给我9个ipcs运行所以我想在这种情况下ipcs的限制和空间限制不是问题

1 个答案:

答案 0 :(得分: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. 编译以下程序(编译器是否发出任何警告?我的确是如此!)
  2. 运行它
  3. 执行ls -ltr
  4. 再次运行
  5. 再次ls -ltr
  6. #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添加到标记中。