Linux共享内存实现进程间通信

原理图:

通过在物理地址上开辟出一块内存,通过页表建立多个进程的虚拟内存与这块内存的映射,让进程可以访问这块空间,映射一旦建立就相当于进程自己拥有了这块内存。

特点:
通信速度快;
生命周期随内核;
不带任何同步机制,所以常常和信号量一块使用。

共享内存的操作:
创建:
int shmget(key_t key, size_t size, int shmflg);
参数描述:
key:由ftok()生成
size:内存的大小,一般设置为页的整数倍,如果小于页的整数倍则实际大小向上取整
shmflg:IPC_CREAT,表示存在获取,不存在创建;IPC_CREAT|IPC_ESCL,不存在创建,存在出错返回
返回值:
成功返回共享内存标识符,失败返回-1。
删除:
删除一般使用 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:标识一个共享内存
cmd:删除时为IPC_RMID
buf:删除时NULL
返回值:
成功返回0, 失败返回-1。
链接共享内存:
共享内存被创建之后,使用时要进行链接
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
shmid:标识一个共享内存
shmaddr:要连接的位置,一般为NULL,这样就交给了操作系统进行处理
shmflg:一般为0
返回值:
成功返回虚拟地址
取链接共享内存:
int shmdt(const void *shmaddr);
参数:
shmaddr:链接内存时返回的虚拟地址
返回值:
成功返回0,失败返回-1

实例代码:
实现父子进程去链接共享内存,子进程写内容,父进程取内容

comm.h
#ifndef _COMM_H_
#define _COMM_H

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

#define PATHNAME "."
#define PJIO_ID 0x666

int createShm();
int getShm();
int destroy();

#endif

comm.c

#include"comm.h"

static int commShm(int flags)
{
    //生成一个key值,用来创建共享内存
    key_t key = ftok(PATHNAME, PJIO_ID);
    if(key < 0)
    {
    perror("ftok");
    return -1;
    }
    //创建共享内存,按照flags形式创建
    int shmid = shmget(key, 4096, flags);
    if(shmid < 0)
    {
    perror("shmid");
    return -2;
    }
    return shmid;
}

int createShm()
{
    //创建
    return commShm(IPC_CREAT|IPC_EXCL|0666);
}
int getShm()
{
    //获取
    return commShm(IPC_CREAT);
}

int destroy(int shmid)
{
    //销毁
    if(shmctl(shmid, IPC_RMID,NULL)<0)
    {
    return -1;
    }
    return 0;
}

myshm.c

#include"comm.h"
int main()
{
    //创建共享内存
    int shmid = createShm();
    //创建子进程
    pid_t id = fork();
    if(id == 0)//子进程
    {
    //子进程连接共享内存
    char *shm = shmat(shmid, NULL, 0);
    int i = 0;
    while(i < 26)
    {
        //每隔一秒写入一个字符
        shm[i] = 'A'+i;
        i++;
        sleep(1);
    }
    shm[i] = '\0';
    //取消于共享内存的连接
    shmdt(shm);
    }
    else//父进程
    {
    //连接共享内存
    char *shm = shmat(shmid, NULL, 0);
           int i = 0;
    while(i<26)
    {
        //每隔一秒,将内存中的数据当作字符串进行访问
        sleep(1);
        printf("%s\n", shm);
        i++;
    }
    //取消与共享内存的连接   
    shmdt(shm);
    //回收子进程
    wait(NULL);
    //销毁共享内存
    destroy(shmid);
    }
    return 0;
}

运行结果:


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值