共享内存错误:在CentOS6.8中,shmat返回NULL,errno(22:无效参数)
这是我等待两个文件共享内存,一个是写入数据共享内存,另一个是从共享内存和printf数据读取数据;但有一些错误。共享内存错误:在CentOS6.8中,shmat返回NULL,errno(22:无效参数)
shm_w.c
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#define MAX_MEM 4096
int main()
{
int shmid;
int ret;
void* mem;
shmid=shmget(0x12367,MAX_MEM,IPC_CREAT | 0666);
printf("shmid is = %d,pid=%d\n",shmid,getpid());
mem=shmat(shmid,(const void*)0,0);
if((int)mem==-1)
{
printf("attach faile.\n");
}
strcpy((char*)mem,"Hello,this is test memory.\n");
ret=shmdt(mem);
return 0;
}
shm_r.c
#include <errno.h>
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#define MAX_MEM 4096
int main()
{
int shmid;
int ret;
void* mem;
shmid=shmget(0x12367,MAX_MEM,0);
mem=shmat(shmid,(const void*)0,0);
//printf("%s\n",(char*)mem);
if(mem==(void*)-1)
{
fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n",errno,strerror(errno));
return 2;
}
printf("%s\n",(char*)mem);
shmdt(mem);
return 0;
}
当我在CentOS6.8编译会把两个.c文件,在第一时间就可以了。
不幸的是,从现在开始,我符文she_w.c是正确太:
的shmid是= 65537,PID = 7116。
但是当我运行shm_r.c,它的出现错误:
shmat return NULL ,errno(22:Invalid argument)
,所以我不知道发生什么事了吗?我试图解决它,例如使用ipcs -m,但不出现shmid。 而我cat/proc/7116/maps: “没有这样的文件或目录”
谁能告诉我发生了什么?我怎样才能在CentOS6.6上找到shmid
uname -r:
2.6.32-504.12.2.el6.x86_64
我也用cat/proc/sysvipc/shm | grep 65537,但不出现shmid。 不幸运!
请告诉我如何解决问题,如果您知道,谢谢!
我已经下载并运行您的程序,无法重现您的[冲突]结果。
要列出活动的shm段,请使用ipcs
命令。如果您需要删除您创建的那个,则可以使用ipcrm
命令。
有两件事情我可以认为的可能是你的问题,但我贴现他们,因为你说你成功运行的第一时间。
段上的权限,因为您第一次创建该段的权限不正确。 ipcs
应该显示这一点。
当您调试编写程序时,它可能做了一些不正确的事情。这可以通过ipcs
来看。如果发生错误,您可以用ipcrm
手动删除该段,然后再次尝试您的程序。
另一种可能性是您的密钥与另一个程序创建的其他段相冲突。这不太可能有两个原因。
你的关键是,可能都是独一无二的。这也可以使用ipcs
现在大多数程序使用0x00000000这是“私人”模式的密钥。这是在程序执行fork
时完成的,但是不是执行execvp
。孩子只需要调用一些功能(例如child_worker
)。父母和孩子使用“私人”细分来回传递数据。由于该细分市场是私密的,因此您不必担心拥有唯一的关键值。
因为你有两个单独的程序,使用该模式将而不是工作你的用例。你需要一个非零的键值,这样你的分段将从一个程序调用到下一个持续。
为了简单起见,我将两个程序组合成一个程序。我还添加了一个选项来删除shm段。
注:我只做了美容清理。我做了而不是修复了任何错误。所以,这只是一个仅供参考的是我在我的系统上测试:
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_MEM 4096
#define XID 0x12367
int opt_cmd;
void
writer(void)
{
int shmid;
void *mem;
shmid = shmget(XID,MAX_MEM,IPC_CREAT | 0666);
printf("shmid is = %d,pid=%d\n",shmid,getpid());
mem = shmat(shmid,NULL,0);
if (mem == (void *) -1) {
printf("attach faile.\n");
}
strcpy((char *) mem,"Hello,this is test memory.\n");
shmdt(mem);
}
void
reader(void)
{
int shmid;
void *mem;
shmid = shmget(XID,MAX_MEM,0);
mem = shmat(shmid,NULL,0);
// printf("%s\n",(char*)mem);
if (mem == (void *) -1) {
fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n",
errno,strerror(errno));
exit(2);
}
printf("%s\n",(char *) mem);
shmdt(mem);
}
void
clean(void)
{
int shmid;
shmid = shmget(XID,MAX_MEM,0);
shmctl(shmid,IPC_RMID,NULL);
}
// main -- main program
int
main(int argc,char **argv)
{
char *cp;
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
cp = *argv;
if (*cp != '-')
break;
switch (cp[1]) {
case 'd':
case 'w':
case 'r':
opt_cmd = cp[1];
break;
default:
break;
}
}
switch (opt_cmd) {
case 'w':
writer();
break;
case 'd':
clean();
break;
default:
reader();
break;
}
return 0;
}
对于使用shmget的()调用,就必须包括<sys/ipc.h>
。
shm_w.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#define MAX_MEM 4096
int main()
{
int shmid;
int ret;
void* mem;
shmid=shmget(0x12367,MAX_MEM,IPC_CREAT | 0666);
printf("shmid is = %d,pid=%d\n",shmid,getpid());
mem=shmat(shmid,(const void*)0,0);
if(mem==(void *) -1)
{
printf("attach faile.\n");
}
strcpy((char*)mem,"Hello,this is test memory.\n");
ret=shmdt(mem);
return 0;
}
shm_r.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h>
#define MAX_MEM 4096
int main()
{
int shmid;
int ret;
void* mem;
shmid=shmget(0x12367,MAX_MEM,0);
mem=shmat(shmid,(const void*)0,0);
//printf("%s\n",(char*)mem);
if(mem==(void *) -1)
{
fprintf(stderr,"shmat return NULL ,errno(%d:%s)\n",errno,strerror(errno));
return 2;
}
printf("%s\n",(char*)mem);
shmdt(mem);
return 0;
}
$ gcc shm_w.c -o shm_w
$ gcc shm_r.c -o shm_r
$ ./shm_w
shmid is = 2293774,pid=5779
$ ./shm_r
Hello,this is test memory.
$ ./shm_r
Hello,this is test memory.
$ ./shm_r
Hello,this is test memory.
'(常量无效*)0' - 使用'NULL'宏来得到一个_NULL指针constant_。 – Olaf
你是一个接一个地运行这两个程序吗?当第一个程序在另一个程序启动之前分离内存段时,您会认为会发生什么?您需要等待另一个程序运行,然后才能分离该段。 –
“你是否一个接一个地运行这两个程序?当第一个程序在另一个程序启动之前分离内存段时,你会认为会发生什么?在分离该段之前,需要等待另一个程序运行。 “为什么在读取程序后必须分离并且不能在写入程序中分离?我的意思是写程序写数据结束,它可以分离,不知为什么当写程序完成时可以使用分离。如果我在写入程序中使用detach,共享内存将被释放,所以读取程序不能读取数据? – Marcos