system V进程间通信-----------共享内存

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37964044/article/details/81591634

共享内存:就是指把一段物理内存(共享内存)映射到不同进程的虚拟地址空间,两个进程只要操纵自己的虚拟地址空间便可访问物理内存,从而实现进程间的通信。

如下图:

要用共享内存进行通信,我们要做到?

1.如何让共享内存映射到你进程的虚拟地址空间

2.如何创建一个共享内存

我们接着往下看

创建或打开共享内存

创建或打开共享内存
函数原型:
int shmget(key_t key,size_t size,int shmflg)
参数:key共享内存的名字
      size表示共享内存的大小
	  shmflg 创建:IPC_CREAT|0644
	         打开:0
返回值:失败返回-1,成功返回该共享内存段的标识码

将共享内存和进程虚拟地址空间挂接

将共享内存连接到虚拟地址空间
函数原型:void* shmat(int shmid,void *shmaddr,int shmflag)
参数:shmid:共享内存标识
      shmaddr:指定连接的地址,一般设置为NULL(一般我们都不知道,要连接那里,你知道哪里没数据码,我不知道。因此设置为NULL,表示让操作系统帮我们选一个)
      shmflg:不关心设置为0
返回值:成功返回:操作系统给你指定的那个虚拟空间上的地址  
        失败返回:-1

将共享内存和进程地址空间脱离

将共享内存和进程虚拟地址空间脱离
函数原型:
int shmdt(const void* shmaddr)
参数:shmaddr:是shmat返回的指针
返回值:成功返回0,失败返回-1

注意:将共享内存和当前进程脱离,并不是说删除了共享内存

用于控制共享内存

用于控制共享内存
函数原型:
int shmctl(int shmid,int cmd,struct shmid_ds* buf)
参数:shmid:共享内存标识码
      cmd:IPC_RMID,表示删除共享内存
      第三个参数不关心置为0
返回值:成功0  失败-1

共享内存这块常用的命令

ipcs -m用于查看共享内存

ipcrm -m  semid用于删除共享内存

ipcrm -M  key用于删除共享内存

共享内存的优点:

是最快的进程间通信方式

原因:一旦和你进程地址空间建立关系,你在自己进程地址空间内操作,就和操作共享内存一样,不用切换到内核,(而消息队列都是先要从用户态切换到内核态,再从内核态切换到用户态。)因此特别快。

共享内存的特点:

1.能够应用于任何进程之间

2.双向通信,每个进程可读,可写

3,没有面向字节流,面向数据块的概念,随机访问内存中数据

4.没有内置同步互斥机制

5.生命周期随内核

简单代码实现:

shmget.c

#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
  int id;
  char name[20];

};
int main()
{
  int shmid=shmget(1234,sizeof(struct stu),IPC_CREAT|0644);
  if(shmid==-1)
  {
   perror("-1");
   exit(1);
  }
  printf("creat ok\n");
  return 0;
 }

read.c

#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
  int id;
  char name[20];

};
int main()
{
  int shmid=shmget(1234,0,0);
  if(shmid==-1)
  {
   perror("-1");
   exit(1);
  }
 struct stu * p=(struct stu*) shmat(shmid,NULL,0);
 printf("p->id=%d,p->name=%s\n",p->id,p->name);
 shmdt(p);
  return 0;
 }

~              

write.c

#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
  int id;
  char name[20];

};
int main()
{
  int shmid=shmget(1234,0,0);
  if(shmid==-1)
  {
   perror("-1");
   exit(1);
  }
 struct stu * p=(struct stu*) shmat(shmid,NULL,0);
 p->id=1;
 strcpy(p->name,"fu rong jie jie");
 sleep(30);
 shmdt(p);
  return 0;
 }

del.c

#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
  int id=shmget(1234,0,0);
  shmctl(id,IPC_RMID,0);


}

猜你喜欢

转载自blog.csdn.net/baidu_37964044/article/details/81591634
今日推荐