进程间通信——共享内存

一、概念

共享内存:允许两个不相关的进程访问同一个逻辑内存,不同进程之间共享的内存通常为同一段物理内存。

进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即回影响到可以访问同一段共享内存的其他进程。


二、共享内存的特点

·共享内存是所有进程间通信最快的(直接是用户到用户)

·不带互斥与同步机制

·生命周期随内核

三、函数

1、shmget函数

功能:用来创建共享内存

原型:


参数:key——这个共享内存段的名字

          size——共享内存的大小

          shmflg——由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的

返回值:成功返回该共享内存的标识码,失败返回-1

2、shmat函数(关联共享内存(映射))

功能:将共享内存段连接到进程地址空间

原型:


参数:shmid——共享内存的标识

          shmaddr——指定连接的地址

          shmflg——它的两个可能取值是SHM_RND和SHM_RDONLY

返回值:成功返回指向共享内存第一个节的指针,失败返回-1

说明:

shmaddr为NULL,核心自动选择一个地址

shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址

shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)

shmflg = SHM_RDONLY:表示连接操作作用来只读共享内存

3、shmdt函数(取消关联(解映射))

功能:将共享内存段与当前进程脱离

原型:


参数:shmaddr——由shmat所返回的指针

返回值:成功返回0,失败返回-1

注意:将共享内存段与当前进程脱离不等于删除共享内存段

4、shmctl函数

功能:用于控制内存

原型:


参数:shmid——由shget返回的共享内存标识码

          cmd——将要采取的动作(有三个可取值)

          buf——指向一个保存着共享内存的模式状态和访问权限的数据结构

返回值:成功返回0,失败返回-1


Makefile

  1 .PHONY:all
  2 all:server client
  3 
  4 client:client.c comm.c
  5     gcc -o $@ $^
  6 server:server.c comm.c
  7     gcc -o $@ $^
  8 
  9 .PHONY:clean
 10 clean:
 11     rm -f client server

comm.h

  1 #ifndef _COMM_H_
  2 #define _COMM_H_
  3 
  4 #include<stdio.h>
  5 #include<sys/types.h>
  6 #include<sys/ipc.h>
  7 #include<sys/shm.h>
  8 #include<stdlib.h>
  9 #include<unistd.h>
 10 
 11 //#define PATHNAME "."
 12 //#define PROJ_ID 0x6666
 13 
 14 int createshm(int size);
 15 int destroyshm(int shmid);
 16 int getshm(int size);
 17 #endif

comm.c

  1 #include "comm.h"
  2 
  3 static int commshm(int size,int flags)
  4 {
  5     key_t _key = ftok(".",0x6666);
  6     if(_key < 0){
  7         perror("ftok");
  8         return -1;
  9     }
 10 
 11     int shmid = shmget(_key,size,flags);
 12     if(shmid < 0){
 13         perror("shmget");
 14         return -2;
 15     }
 16     return shmid;
 17 }
 18 
 19 int destroyshm(int shmid)
 20 {
 21     if(shmctl(shmid,IPC_RMID,NULL) < 0){
 22         perror("shmctl");
 23         return -1;
 24     }
 25     return 0;
 26 }
 27 
 28 int createshm(int size)
 29 {
 30     return commshm(size,IPC_CREAT|IPC_EXCL|0666);
 31 }
 32 
 33 int getshm(int size)
 34 {
 35     return commshm(size,IPC_CREAT);
 36 }

server.c

  1 #include "comm.h"
  2 
  3 int main()
  4 {
  5     int shmid = createshm(1024);
  6     printf("create shm success\n");
  7 
  8     char *addr = shmat(shmid,NULL,0);
  9     sleep(2);
 10     int i = 0;
 11     while(i++ < 26){
 12         printf("client:> %s\n",addr);
 13         sleep(1);
 14     }
 15     shmdt(addr);
 16     sleep(2);
 17     destroyshm(shmid);
 18     return 0;
 19 }

client.c

  1 #include "comm.h"
  2 
  3 int main()
  4 {
  5     int shmid = getshm(1024);
  6     sleep(1);
  7     char *addr = shmat(shmid,NULL,0);
  8     sleep(2);
  9     int i = 0;
 10     while(i < 26){
 11         addr[i] = 'A' + i;
 12         i++;
 13         addr[i] = 0;
 14         sleep(1);
 15     }
 16     shmdt(addr);
 17     return 0;
 18 }


查看共享内存


删除共享内存(不是必须手动删除)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值