共享内存是第二种IPC工具。他允许两个无关的进程访问相同的逻辑内存。共享内存是在两个运行的程序之间传递数据的有效手段。尽管X/Open标准并没有要求,很可能绝大数的共享内存实现都是会将不同进程之间正在共享的内存安排在相同的物理内存中。
共享内存为在多个进程之间共享与传递数据提供一个有效的手段。因为他并没有提供同步的方法,所以通常我们需要使用其他的机制来同步对共享内存的访问。通常,我们也许会使用共享内存来提供对大块内存区的有效访问,并且传递少量的消息来同步对此内存的访问。
向共享内存存放带有指针的结构体时,当再次向共享内存取出这个指针的值时,会出现内存错误。
结构体结构如下:
typedef
struct base_array{
int size ;
int count ;
struct base
*data;
}base_array;
程序大致如下:
int main(){
shmid=shmget(key,SHARED_SEGMENT_SIZE,0666 | IPC_EXCL) ; //创建共享内存
if(fork()==0) { //子进程
shmptr=(base_array *)shmat(shmid,0,0); //拿到共享内存的首地址
L->size =
number; //初始化L(base_array型)
L->count = 0 ;
for(i=0;i<number;i++){
sprintf(string,"%d",i) ;
strcpy(L->data[i].id,string)
;
L->data[i].next = NULL
;
L->count++
;
}
memcpy(shmptr,&L,(sizeof(base)+sizeof(base_array))*(L.count));//将L的东西复制给shmptr
sem_v(semid) ; //互斥
}else{ //父进程
shmptr=(base_array *)shmat(shmid,0,0); //拿到共享内存的首地址
sem_p(semid); //互斥
printf("size=%d\n",shmptr->size); //成功
printf("count=%d\n",shmptr->count); //成功
printf("L->data[0]=%s\n",shmptr->data[0].id); //失败
}
}
分析: size和count打印成功,而data[0].id打印失败。因为,size和count已经从子进程的内存中复制到了共享内存中了,而仅仅是把data的指针值复制到了共享内存里面,而真正的
内容仍然在子进程的内存里面。当主进程去取这个值的时候,系统是在共享内存里面寻址,所以肯定会导致错误。