访问共享内存段的进程返回不同的值
Posted
技术标签:
【中文标题】访问共享内存段的进程返回不同的值【英文标题】:Processes accessing a Shared Memory segment returning different values 【发布时间】:2017-11-15 13:28:03 【问题描述】:我是 IPCS 概念的新手,我想实现一个进程创建并初始化共享内存,然后调用另一个进程,该进程附加到同一共享内存段并打印共享内存中的数据。 但是我无法实现它:
AlgoCommon.h
struct sub_algo_shm
int time;
int pno;
;
struct AlgoShm
int head;
int tail;
char fFlag;
struct sub_algo_shm algoshm;
;
AlgoThrottle.c
#define key (key_t)111119
#define SHM_SIZE 1024
int main()
int shmid ;
struct timeval CurTime;
struct timespec nTime;
struct AlgoShm *shmaddr,*ptr;
ptr = (struct AlgoShm *)malloc(10*sizeof(struct AlgoShm));
//Creating Shared Memory
if((shmid = shmget(key,SHM_SIZE,0644 |IPC_CREAT)) < 0)
perror("shmget:error");
else
printf("Shm created key=[%d] \n Segment Id [%d] ",key,shmid);
//Attaching to Shared Memory
shmaddr = (struct AlgoShm *)shmat(shmid,0,0);
if(shmaddr < 0)
perror(" shmat :error");
else
printf(" SHM Segment attached at [%x] ",shmaddr);
//Loading/Initializing Data Blocks in SHM
clock_gettime(CLOCK_REALTIME,&nTime);
printf(" Time in N secs[%ld] \n ",nTime.tv_nsec);
ptr->head = 5;
ptr->tail = 3;
ptr->fFlag = '0';
ptr->algoshm.time = 0;
ptr->algoshm.pno = 1;
//memcpy(shmaddr,&ptr,sizeof(ptr));
printf(" AlgoThrottle|ptr->head [%d] ",ptr->head);
// sleep(1);
system("./AlgoRead");
return 0;
AlgoRead.c
#define key (key_t)111119
#define SHM_SIZE 1024
int main()
int shmid ;
struct AlgoShm *shmaddr,*ptr1 ;
ptr1 = (struct AlgoShm *)malloc(10*sizeof(struct AlgoShm));
if((shmid = shmget(key,SHM_SIZE,0)) < 0)
perror(" AlgoRead|shmget:error ");
else
printf(" AlgoRead|SHM Created shmid [%d] ",shmid);
if((shmaddr = (struct AlgoShm *)shmat(shmid,0,0)) < 0)
perror("AlgoRead|shmat error");
else
//memcpy(ptr1,shmaddr,sizeof(struct AlgoShm));
printf(" AlgoRead|Attached to Segment at Address[%x] \n ",shmaddr);
printf(" AlgoRead|ptr1->head [%d] ptr1->tail [%d] ptr1->fFlag[%c] \n ",ptr1->head,ptr1->tail,ptr1->fFlag);
return 0;
这是我的输出:
Shm created key=[111119]
Segment Id [1179615678] SHM Segment attached at [4a6b4000] Time in N secs[114594083]
AlgoRead|SHM Created shmid [1179615678] AlgoRead|Attached to Segment at Address[624cb000]
AlgoRead|ptr1->head [36810768] ptr1->tail [0] ptr1->fFlag[▒]
AlgoThrottle|ptr->head [5]
此外,系统调用的输出首先显示,然后是 printf 语句,即使在我调用 system() 之前使用了 sleep(1) 之后也是如此
【问题讨论】:
什么是key
?它在哪里定义?请发布完整代码。
用键编辑,在同一个地方定义
你在哪里定义结构“AlgoShm”? head、tail 和 fFlag 是这个结构的成员吗?
它们被定义在一个包含在两个进程中的头文件中,编辑了代码。
当我在两个进程中评论那些'memcpy'时,我为第二个进程的头和尾都得到0,似乎它显示的是结构的默认值,而不是共享内存中的那个。
【参考方案1】:
首先,如果您使用的是shared memory
,那么为什么要使用malloc()
?共享内存本身会附加 shmid
和 shared memory
你不必显式地做 malloc()。
第二件事,您将shmaddr
指针与shmat()
返回的内存附加在一起,但将数据 放入ptr
,ptr 附加到堆内存不与共享内存。所以要么将数据放入shmaddr
指针中,要么替换这个
shmaddr = (struct AlgoShm *)shmat(shmid,0,0);
与
ptr = (struct AlgoShm *)shmat(shmid,0,0);
并且不要使用 mallocc() 分配内存。然后做
ptr->head = 5;
ptr->tail = 3;
ptr->fFlag = '0';
ptr->algoshm.time = 0;
ptr->algoshm.pno = 1;
在这两个过程中进行所有这些修改。最后你应该使用shmdt()
来解除共享内存,否则它将是memory leakage
。
我将您的代码修改为 one.c:
int main()
int shmid ;
struct timeval CurTime;
struct timespec nTime;
struct AlgoShm *shmaddr,*ptr;
if((shmid = shmget(key,SHM_SIZE,0644 |IPC_CREAT)) < 0)
perror("shmget:error");
else
printf("Shm created key=[%d] \n Segment Id [%d] ",key,shmid);
ptr = (struct AlgoShm *)shmat(shmid,0,0);
if(shmaddr < 0)
perror(" shmat :error");
else
printf(" SHM Segment attached at [%x] ",ptr);
clock_gettime(CLOCK_REALTIME,&nTime);
printf(" Time in N secs[%ld] \n ",nTime.tv_nsec);
ptr->head = 5;
ptr->tail = 3;
ptr->fFlag = 'a';
ptr->algoshm.time = 10;
ptr->algoshm.pno = 11;
printf(" AlgoThrottle|ptr->head [%x] ",ptr->head);
system("./AlgoRead");
return 0;
两个.c:
int main()
int shmid ;
struct AlgoShm *shmaddr,*ptr1 ;
if((shmid = shmget(key,SHM_SIZE,0)) < 0)
perror(" AlgoRead|shmget:error ");
else
printf(" AlgoRead|SHM Created shmid [%d] ",shmid);
if((ptr1 = (struct AlgoShm *)shmat(shmid,0,0)) < 0)
perror("AlgoRead|shmat error");
else
printf(" AlgoRead|Attached to Segment at Address[%x] \n ",ptr1);
printf(" AlgoRead|ptr1->head [%d] ptr1->tail [%d] ptr1->fFlag[%c] \n ",ptr1->head,ptr1->tail,ptr1->fFlag);
shmdt(ptr1);
return 0;
希望对你有所帮助,我给你的建议是正确浏览 shmget()、shmat() 和 shmdt() 的手册页。
【讨论】:
【参考方案2】:请在下方查看您的错误 为什么要分配 10 倍的结构?
正确的行
ptr = (struct AlgoShm *)malloc(10*sizeof(struct AlgoShm));
到:-
ptr = (struct AlgoShm *)malloc(sizeof(struct AlgoShm));
对两个 c 文件进行上述更改
现在在memcpy
,为什么要提供指针ptr
的地址,比如&ptr
?只需删除&
。这不是一个对象,因此您只需要提供指针ptr
。像下面这样更正它
memcpy(shmaddr,ptr,sizeof(ptr));
而不是memcpy
更好地使用如下。
shmaddr->head = ptr->head;
shmaddr->tail = ptr->tail;
shmaddr->fFlag=ptr->fFlag;
我在下面重写了你的代码。试试看。最好按照我的建议更正您自己的代码。
AlgoThrottle.c
int main()
int shmid ;
struct timeval CurTime;
struct timespec nTime;
struct AlgoShm *shmaddr,*ptr;
ptr = (struct AlgoShm *)malloc(sizeof(struct AlgoShm));
//Creating Shared Memory
if((shmid = shmget(key,SHM_SIZE,0644 |IPC_CREAT)) < 0)
perror("shmget:error");
else
printf("Shm created key=[%d] \n Segment Id [%d] ",key,shmid);
//Attaching to Shared Memory
shmaddr = (struct AlgoShm *)shmat(shmid,0,0);
if(shmaddr < 0)
perror(" shmat :error");
else
printf(" SHM Segment attached at [%x] ",shmaddr);
//Loading/Initializing Data Blocks in SHM
clock_gettime(CLOCK_REALTIME,&nTime);
printf(" Time in N secs[%ld] \n ",nTime.tv_nsec);
ptr->head = 5;
ptr->tail = 3;
ptr->fFlag = '0';
ptr->algoshm.time = 0;
ptr->algoshm.pno = 1;
//memcpy(shmaddr,ptr,sizeof(ptr));
shmaddr->head = ptr->head;
shmaddr->tail = ptr->tail;
shmaddr->fFlag=ptr->fFlag;
printf(" AlgoThrottle|ptr->head [%d] \n",ptr->head);
//sleep(1);
system("./AlgoRead");
return 0;
AlgoRead.c
int main()
int shmid ;
struct AlgoShm *shmaddr,*ptr1 ;
ptr1 = (struct AlgoShm *)malloc(sizeof(struct AlgoShm));
if((shmid = shmget(key,SHM_SIZE,0)) < 0)
perror(" AlgoRead|shmget:error ");
else
printf(" AlgoRead|SHM Created shmid [%d] ",shmid);
if((shmaddr = (struct AlgoShm *)shmat(shmid,0,0)) < 0)
perror("AlgoRead|shmat error");
else
memcpy(ptr1,shmaddr,sizeof(struct AlgoShm));
printf(" AlgoRead|Attached to Segment at Address[%x] \n ",shmaddr);
printf(" AlgoRead|ptr1->head [%d] ptr1->tail [%d] ptr1->fFlag[%c] \n ",ptr1->head,ptr1->tail,ptr1->fFlag);
return 0;
【讨论】:
以上是关于访问共享内存段的进程返回不同的值的主要内容,如果未能解决你的问题,请参考以下文章