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

Posted

技术标签:

【中文标题】第二个 shmget 总是返回拒绝访问【英文标题】:Second shmget always returns access denied 【发布时间】:2014-11-16 15:26:52 【问题描述】:

我正在尝试创建两组共享内存段。一个存储整数,另一个存储字符串。 当我为我的整数创建共享内存段时,我在第二个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,但我尝试了不同的键,结果始终相同。我做错了吗?

当我调用shmget 时,我尝试从特权中删除0666,它确实停止了(shmget 不返回-1),让我们复制内容,但是当我尝试从中获取内容时,我得到了分段错误。

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

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

【问题讨论】:

errno 告诉你什么?您的系统配置为支持多少个共享内存段? (不太可能只有一个,但也许其他的已经在使用。)第二个密钥是否已经被其他程序使用? ipcs 向您展示了什么?当由root 运行时? (我看到您说它没有向您显示任何内容,并且您尝试更改具有相同效果的键。)它是否会因为您尝试创建太的段而失败?这是一个shmmin 内核参数,也许整数集太小了?我担心你的字符串空间的大小。 好吧,我在内核中创建了字符串指针,而不是实际的字符串。现在对于最大 ipcs,我认为我没有达到极限,因为我碰巧同时运行了 5 个不同的程序,所有程序都创建了与我在共享内存之上的代码相同的大小,并且它工作正常。除非问题是一个进程不能创建两个不同的共享内存段。我目前拥有和工作的是我将这两个段合并为一个仅包含字符串的段,并在发送之前将整数转换为字符串。所以我认为共享内存空间不是问题。 运行 ipcs 返回一些由系统应用程序和我的应用程序控制的 ipcs。我的旧代码的总字节数是 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)

为了演示,

    编译以下程序(您的编译器是否发出任何警告?我的有!) 运行它 做ls -ltr 再次运行 再次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 添加到标志中。

【讨论】:

不,它没有。只需检查您的优先级图表。 (这种错误多见于open(),但它当然适用于任何函数调用) 忘记我的最后一条评论,我是反过来读的(这就是为什么我说请描述一下,因为它有点不可读,但仍然是我最初的错误)。是的,这就是导致我的错误的原因

以上是关于第二个 shmget 总是返回拒绝访问的主要内容,如果未能解决你的问题,请参考以下文章

VC++ 2008,OpenProcess 总是返回错误 5(拒绝访问)

Spring Security 总是返回 HTTP 403 访问被拒绝 [关闭]

为啥使用CMD命令中的find命令总是拒绝访问?

我的电脑 Internet Explorer点击后显示拒绝访问 请问啥意思

MySQL授予权限访问拒绝

连接网络打印机出现端口拒绝访问的问题