进程间通信——共享内存

共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程地址空间,这些进程间数据传递将不在涉及到内核,但任何事都有二义性,它是一个临界资源,但这样的方法却没有给提供任何保护。


如图:


 将共享区的代码通过页表映射到不同的PCB下,就可以实现共享内存,


以下为系统调用:

int shmget(key_t key,size_t size,int shflg);  //创建共享内存
void* shmat(int shmid,const char* shmaddr,int shmflg);  //映射关系

参数:

        shmid:共享内存标识符

        shmaddr:指定要连接的地址,为NULL时,自动选择一个地址

        shmflg:设置共享内存特性,一般为0

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

int shmdt(const char* shmaddr);  //断开映射关系
int shmctl(int shmid,int cmd,struct shmid_da* buf);  //控制共享内存

以下是代码实现:

comm.h

#pragma once

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

#define PATHNAME "."
#define PROJ_ID 0x6666

int createShm(int size);

int destoryShm(int shmid);

int getShm(int size);

comm.c

#include<stdio.h>
#include"comm.h"

static int commShm(int size,int flags)
{
    key_t k = ftok(PATHNAME,PROJ_ID);
    if (k<0)
    {
        perror("ftok");
        return -1;
    }
    int shmid = 0;
    if((shmid = shmget(k,size,flags)) < 0)
    {
        perror("shmget");
        return -2;
    }
    return shmid;
}

int destoryShm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,NULL) < 0)
    {
        perror("shmctl");
        return -1;
    }
    return 0;
}

int createShm(int size)
{
    return commShm(size,IPC_CREAT|IPC_EXCL|0666);
}

int getShm(int size)
{
    return commShm(size,IPC_CREAT);
}

server.c

#include<stdio.h>
#include"comm.h"

int main()
{
    int shmid = createShm(4096);
    char *addr = shmat(shmid,NULL,0);
    sleep(2);
    int i = 0;
    while(i++ < 26)
    {
        printf("Client# %s\n",addr);
        sleep(1);
    }
    shmdt(addr);
    sleep(2);
    destoryShm(shmid);
    return 0;
}

client.c

#include<stdio.h>
#include"comm.h"

int main()
{
    int shmid = getShm(4096);
    sleep(1);
    char* addr = shmat(shmid,NULL,0);
    sleep(2);
    int i = 0;
    while(i < 26)
    {
        addr[i] = 'A' +i;
        i++;
        addr[i] = 0;
        sleep(1);
    }
    shmdt(addr);
    sleep(2);

    return 0;
}

结果可以自己实验一下,但是和消息队列一样,它的生命周期也是随内核,故需要用

ipcs -m //查看
ipcrm -m//删除 IPC资源


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值