System V 共享内存

引言:

再上一章中,我们知道了可以通过管道进行进程间通信,但是管道通信要经过进程->内核->进程,一共两次拷贝,效率偏低。而今天我们要学习的System V 共享内存将是最快的通信方式。

共享内存示意图

在这里插入图片描述

  • 过程:
    当一个进程(A)申请共享空间之后,操作系统会在物理内存中开辟一片资源,通过页表映射到A,B进程的地址空间(共享区)中,实现实时通信。

共享内存的特点:

  • 1.共享内存是最快的ipc形式(因为不需要拷贝,仅仅需要物理内存映射)
  • 2.共享内存由操作系统创建,交给用户管理。
  • 3.共享内存不提供同步与互斥(交由用户自己维护)

共享内存相关函数

  • shmget
功能:创建共享内存
原型:int shemget(key_t key , size_t size, int shmflg );
参数:
key:这个共享内存段名字(自己定义)
size:共享内存大小(自己定义)
shmflg:由九个权限标志构成,和创建文件时的权限是一样的。
返回值:
成功返回共享内存段的标识码。失败返回-1
  • shmat函数
功能:将共享内存连接到进程地址空间
原型:int shmat(int shmid, const void* smaddr, int shmflg)
参数:
shmid:共享内存标识
shmaddr:指定链接地址
shmflg:权限位(大多使用SHM_RND和SHM_RDONLY)
返回值:
成功返回共享内存的首地址,失败返回-1.
  • shmat函数
功能:将共享内存与当前进程脱离
原型:int shmdt(const void* shmaddr);
参数:
shmaddr:由shmat返回的指针
返回值:
成功返回0,失败返回-1
注意:
将共享内存与当前内存脱离,并不等于删除共享内存码。
如果想删除共享内存用(ipcs查询编号 + ipcrm -m 删除共享内存)
  • shmctl函数
功能:用于控制共享内存:
原型:int shmctl(int shmid, int cmd, struct shmid_ds * buf);
参数:
 shmid:由shmget返回的指针
 cmd:可能采取的动作(有三个可取值)
 buf:指向一个保存着共享内存的模式状态和访问权限的数据结构(这里我们设置位0)
 
  • ipcs命令
    查看物理空间
    -ipcs -m + id命令
    删除指定ID

创建共享内存

  • 1.步骤:
    • 在物理内存中开辟空间
    • 这一片物理内存映射进两个虚拟地址的共享区
  • 2.代码:
    客户端:
 #include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main()
{
    key_t k = ftok("Makefile", 0x6666);//创建随机值
    if(k < 0)
    {
        printf("ftok error\n");
        return 1;
    }
    int sh_mid = shmget(k, 4096, 0);//链接共享内存
    if(sh_mid < 0)
    {
        printf("shmget error\n");
        return 2;
    }
    char* p = (char*)shmat(sh_mid, NULL, 0);//绑定共享内存
    int i = 0;
    while(i < 4096)
    {
        p[i] = 'a' + i;
        i++;
        p[i] = 0;
        sleep(1);
    }



    shmdt(p);//与共享内存断开
    return 0;
}

服务端:

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main()
{
    key_t k = ftok("Makefile", 0x6666);
    if(k < 0)
    {
        printf("ftok error\n");
        return 1;
    }
    int sh_mid = shmget(k, 4096, IPC_CREAT | IPC_EXCL);//创建新的共享内存
    if(sh_mid < 0)
    {
        printf("shmget error\n");
        return 2;
    }
    char* p = (char*)shmat(sh_mid, NULL, 0);
    int i = 0;
    while(i < 4096)
    {
        printf("%s\n", p);
        i++;
        sleep(1);
    }



    shmdt(p);
    shmctl(sh_mid, IPC_RMID, NULL);//释放共享内存
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值