进程间通信之: 共享内存
3.使用实例
该实例说明如何使用基本的共享内存函数。首先是创建一个共享内存区(采用的共享内存的键值为IPC_PRIVATE,是因为本实例中创建的共享内存是父子进程之间的共用部分),之后创建子进程,在父子两个进程中将共享内存分别映射到各自的进程地址空间之中。
父进程先等待用户输入,然后将用户输入的字符串写入到共享内存,之后往共享内存的头部写入“WROTE”字符串表示父进程已成功写入数据。子进程一直等到共享内存的头部字符串为“WROTE”,然后将共享内存的有效数据(在父进程中用户输入的字符串)在屏幕上打印。父子两个进程在完成以上工作之后,分别解除与共享内存的映射关系。
最后在子进程中删除共享内存。因为共享内存自身并不提供同步机制,所以应该额外实现不同进程之间的同步(例如:信号量)。为了简单起见,在本实例中用标志字符串来实现非常简单的父子进程之间的同步。
这里要介绍的一个命令是ipcs,这是用于报告进程间通信机制状态的命令。它可以查看共享内存、消息队列等各种进程间通信机制的情况,这里使用了system()函数用于调用shell命令“ipcs”。程序源代码如下所示:
/*shmem.c*/
#includesys/types.h>
#includesys/ipc.h>
#includesys/shm.h>
#includestdio.h>
#includestdlib.h>
#includestring.h>
#defineBUFFER_SIZE2048
intmain()
{
pid_tpid;
intshmid;
char*shm_addr;
charflag[]=WROTE;
char*buff;
/*创建共享内存*/
if((shmid=shmget(IPC_PRIVATE,BUFFER_SIZE,0666))0)
{
perror(shmget);
exit(1);
}
else
{
printf(Createshared-memory:%dn,shmid);
}
/*显示共享内存情况*/
system(ipcs-m);
pid=fork();
if(pid==-1)
{
perror(fork);
exit(1);
}
elseif(pid==0)/*子进程处理*/
{
/*映射共享内存*/
if((shm_addr=shmat(shmid,0,0))==(void*)-1)
{
perror(Child:shmat);
exit(1);
}
else
{
printf(Child:Attachshared-memory:%pn,shm_addr);
}
system(ipcs-m);
/*通过检查在共享内存的头部是否标志字符串WROTE来确认
父进程已经向共享内存写入有效数据*/
while(strncmp(shm_addr,flag,strlen(flag)))
{
printf(Child:Waitforenabledata...n);
sleep(5);
}
/*获取共享内存的有效数据并显示*/
strcpy(buff,shm_addr+strlen(flag));
printf(Child:Shared-memory:%sn,buff);
/*解除共享内存映射*/
if((shmdt(shm_addr))0)
{
perror(shmdt);
exit(1);
}
else
{
printf(Child:Deattachshared-memoryn);
}
system(ipcs-m);
/*删除共享内存*/
if(shmctl(shmid,IPC_RMID,NULL)==-1)
{
perror(Child:shmctl(IPC_RMID)n);
exit(1);
}
else
{
printf(Deleteshared-memoryn);
}
system(ipcs-m);
}
else/*父进程处理*/
{
/*映射共享内存*/
if((shm_addr=shmat(shmid,0,0))==(void*)-1)
{
perror(Parent:shmat);
exit(1);
}
else
{
printf(Parent:Attachshared-memory:%pn,shm_addr);
}
sleep(1);
printf(nInputsomestring:n);
fgets(buff,BUFFER_SIZE,stdin);
strncpy(shm_addr+strlen(flag),buff,strlen(buff));
strncpy(shm_addr,flag,strlen(flag));
/*解除共享内存映射*/
if((shmdt(shm_addr))0)
{
perror(Parent:shmdt);
exit(1);
}
else
{
printf(Parent:Deattachshared-memoryn);
}
system(ipcs-m);
waitpid(pid,NULL,0);
printf(Finishedn);
}
exit(0);
}
linux操作系统文章专题:linux操作系统详解(linux不再难懂)
评论