共享内存可以说最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A,B共享内存的意思是,同一块物理内存被映射到进程A,B各自的进程地址空间。进程A可以及时看到进程B对共享内存中数据的更新,反之亦然 。由于多个进程共享同一块内存区域,必然需要某种同步机制 ,互斥锁和信号量都可以。
创新互联建站是网站建设专家,致力于互联网品牌建设与网络营销,专业领域包括网站设计、网站建设、电商网站制作开发、重庆小程序开发、微信营销、系统平台开发,与其他网站设计及系统开发公司不同,我们的整合解决方案结合了恒基网络品牌建设经验和互联网整合营销的理念,并将策略和执行紧密结合,且不断评估并优化我们的方案,为客户提供全方位的互联网品牌整合方案!
采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝,对于管道和消息队列等通信方式,则需要在内核和用户空间进行4次的数据拷贝,而共享内存则只拷贝两次数据,一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样数据内容一直保存在共享内存中,并没有写回文件,共享内存中的内容是在解除映射时才写回文件的。因此,采用共享内存的效率是非常高的。
下面我们来写一段程序来看看共享内存的应用:
comm.c文件:
#include "comm.h"
int comm_shm_creat(int flag)
{
key_t _key=ftok(_PATH_,_PROJ_ID_);
if(_key<0)
{
perror("ftok");
return -1;
}
int shm_id=shmget(_key,_SIZE_,flag);
if(shm_id<0)
{
perror("shmget");
return -1;
}
return shm_id;
}
int shm_creat()
{
umask(0);
int flag=IPC_CREAT|IPC_EXCL|0666;
return comm_shm_creat(flag);
}
int shm_get()
{
int flag=IPC_CREAT;
return comm_shm_creat(flag);
}
int shm_destroy(int shm_id)
{
if(shmctl(shm_id,IPC_RMID,NULL)<0)
{
perror("shmctl");
return -1;
}
return 0;
}
void* at_shm(int shm_id)
{
return shmat(shm_id,NULL,0);
}
int dt_shm(void *addr)
{
return shmdt(addr);
}
shm_server.c文件:
#include "comm.h"
int main()
{
int shm_id=shm_creat();
char *start=at_shm(shm_id);
int i=0;
for(;i<_SIZE_;++i)
{
printf("%s\n",start);
sleep(1);
}
dt_shm(start);
shm_destroy(shm_id);
return 0;
}
shm_client.c文件:
#include "comm.h"
int main()
{
int shm_id=shm_get();
char *start=at_shm(shm_id);
int i=0;
for(;i<_SIZE_;++i)
{
start[i]='A';
start[i+1]='\0';
sleep(1);
}
dt_shm(start);
return 0;
}
运行结果如下:
从上图结果可以看到,他们shmget的ID相同,而且client写的内容被server接收到了,实现了进程间通信的目的。