进程间通信——共享内存

原创 2018年04月15日 12:18:32

共享内存区是最快的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资源


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

进程间通信方式总结——共享内存

Linux/Unix系统IPC是各种进程间通信方式的统称,但是其中极少能在所有Linux/Unix系统实现中进行移植。随着POSIX和Open Group(X/Open)标准化的推进呵护影响的扩大...
  • tf_apologize
  • tf_apologize
  • 2017-04-16 11:36:59
  • 929

VC用共享内存实现进程间通信

  • 2012年01月11日 14:58
  • 73KB
  • 下载

进程间通信之共享内存:shm

shm代码#include #include #include int main(int argc, const char *argv[]){ struct shm////共享内存使用的结...
  • u011011827
  • u011011827
  • 2017-02-22 20:46:11
  • 395

C#进程间通信-共享内存代码实例

  • 2013年12月04日 08:03
  • 73KB
  • 下载

【Linux】进程间通信(IPC)之共享内存详解与测试用例

学习环境centos6.5 Linux内核2.6什么是共享内存共享内存允许两个或更多进程访问同一块内存。当一个进程改变了这块内存中的内容的的时候,其他进程都会察觉到这个更改。效率:因为所有进程共享同一...
  • a1414345
  • a1414345
  • 2017-04-06 14:54:54
  • 1237

进程间通信:共享内存(代码实现)

共享内存:1.共享内存就是允许两个不相关的进程访问同一个逻辑内存;                     2.共享内存是在两个正在运行的进程之间共享和传递数据的一种最有效的方式;        ...
  • wangiijing
  • wangiijing
  • 2016-07-06 18:17:36
  • 4380

进程间通信之共享内存初步

基本概念共享内存   共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。  ...
  • lzjsqn
  • lzjsqn
  • 2016-12-24 22:32:15
  • 773

【Linux进程间通信】 - 共享内存

今天我们来介绍Linux下最高效的一种进程间通信方式 – 共享内存。什么是共享内存?顾名思义,共享内存就是两个(或多个)进程共同占有一段内存空间,这些进程可以是有亲缘关系的进程,也可以是完全不相...
  • Xiejingfa
  • Xiejingfa
  • 2016-03-14 20:54:38
  • 3639

Windows上C++使用共享内存进行进程间通讯

共享内存 (也叫内存映射文件) 主要是通过映射机制实现的 , Windows 下进程的地址空间在逻辑上是相互隔离的 , 但在物理上却是重叠的 ; 所谓的重叠是指同一块内存区域可能被多个进程同时使用 ,...
  • tojohnonly
  • tojohnonly
  • 2017-04-19 22:54:40
  • 2366

java进程间通讯机制代码----RMI、共享内存、Socket、管道

  • 2012年11月20日 14:29
  • 310KB
  • 下载
收藏助手
不良信息举报
您举报文章:进程间通信——共享内存
举报原因:
原因补充:

(最多只允许输入30个字)