第二个 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 访问被拒绝 [关闭]