Linux进程通信之共享内存

今天我为大家讲的是进程间通信的第二种方法——共享内存。首先我们得理解一下什么是共享内存以及共享内存通信的原理。

共享内存其实就是os在内存上面开辟的一段空间,让不同的进程通过虚拟地址进程空间一起看到这同一块内存,以下是共享内存原理示意图:

Linux进程通信之共享内存_第1张图片

 创建一个共享内存:

Linux进程通信之共享内存_第2张图片

参数key是内核层标定共享内存唯一性的,因为os创建了许多共享内存,为了能让不同的进程找到同一个共享内存,就用key来标识。因为有很多的共享内存需要被管理,所以os也是采用了先描述后组织的方法,通过数据结构(数组)把共享内存管理起来。所以该函数的返回值就是用户层标识共享内存的,相当于文件描述符。参数size创建共享内存的大小。参数shmflg是创建模式:

Linux进程通信之共享内存_第3张图片

IPC_CREAT:如果共享内存不存在就创建,存在就获取共享内存。

IPC_EXCL:1.它不能够被单独使用。2.如果不存在,创建之。如果不存在,就返回报错。

所以IPC_EXCL能够保证创建出来的共享内存是新创建的!!

该函数的返回值:

创建一个参数key:

key是为了标识共享内存唯一性的,所以在调用shmget系统调用的时候,需要将key传进去。其实可以告诉大家的是共享内存的内核数据结构里面就存有了可key,所以说key相当于共享内存的一种属性。以下是创建key的函数:

Linux进程通信之共享内存_第4张图片

 它的返回值:

共享内存创建好了并且两个进程都找到了同一块时,就需要将共享内存的起始地址写到进程的虚拟地址空间里面。

进程与共享内存的挂接:

Linux进程通信之共享内存_第5张图片

它的返回值:

如果成功了,返回的是共享内存的起始地址,如果失败了返回-1.

取消挂接:

 int shmdt(const void *shmaddr);

接口很简单,只需要将共享内存的起始地址填入就行。

查看共享内存接口:

ipcs -m 

删除共享内存接口:

ipcrm -m + shmid

shmct函数 :

功能:用于控制共享内存
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid: shmget 返回的共享内存标识码
cmd: 将要采取的动作(有三个可取值)
buf: 指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回 0 ;失败返回 -1

 Linux进程通信之共享内存_第6张图片

了解完了上面所有函数接口,现在我们实现一个用共享内存实现进程间通信的代码:

com.hpp:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

#define PATH_NAME "/tmp"
#define PROJ_ID 0X123
#define MAX_SIZE 4096
key_t getkey()
{
    key_t key =ftok(PATH_NAME,PROJ_ID);
    if(key ==-1)
    {
        cerr<<"getkey:"<

client.cc:

#include "com.hpp"

int main()
{
    //创建和服务端相同的key值
    key_t key =getkey();

    //获取共享内存
    int shmid =getShm(key);
    printf("shmid: %d\n", shmid);

    //将客户端和进程挂接起来
    char* start =(char*)AttachShm(shmid);
    cout<<"client 挂接成功 address: "<0)
        {
            buffer[strlen(buffer)-1]=0;
        }
        int cnt =1;
        char buffer1[1024];
        snprintf(buffer1,sizeof(buffer1),"我是客户端,我正在给你发消息[%d][%d]:%s",getpid(),cnt++,buffer);
        memcpy(start,buffer1,strlen(buffer1));
    }

    //客户端解除挂接
    DetachShm(start);
    

    return 0;

}

server.cc:

#include "com.hpp"

int main()
{
    //获取一个key
    key_t key =getkey();
    
    //创建共享内存
    int shmid =createShm(key);
    //将进程和共享内存进行挂接
    char* start =(char*)AttachShm(shmid);
    printf("server 挂接成功 ,address: %p",start);

    //服务端读取数据。
    while(true)
    {
        cout<<"client say: "<

最后我们来谈一谈共享内存的优缺点

优先:

共享内存是进程间通信最快的一种方式,大大减少了拷贝。

 Linux进程通信之共享内存_第7张图片

缺点:

不给我进行同步与互斥的操作,对数据没有做任何保护。

共享内存相关知识就全部介绍清楚了,感谢大家多多支持!! 

你可能感兴趣的:(linux,运维,服务器)